Back to index

nordugrid-arc-nox  1.1.0~rc6
Classes | Enumerations | Functions | Variables
ARex Namespace Reference

Classes

class  ARexConfigContext
class  CountedResourceLock
class  CountedResource
class  OptimizedInformationContainer
class  ARexService
class  ConfigError
 Error configuration class. More...
class  Option
class  ConfGrp
class  Config
 Core configuration class. More...
class  ConfigIO
 Virtual base-class for reading and writing configuration files. More...
class  NGConfig
 Configuration class used for reading configuration files ARC-style. More...
class  XMLConfig
 Class for reading in configuration files in xml-format. More...
struct  sleep_st
struct  args_st
class  GridManager
class  PrefixedFilePayload
class  ARexGMConfig
class  ARexJob
 This class represents convenience interface to manage jobs handled by Grid Manager. More...
class  LoggerClient
class  JobRecord
class  PayloadFile
 Implementation of PayloadRawInterface which provides access to ordinary file. More...
class  PayloadBigFile

Enumerations

enum  ARexJobFailure {
  ARexJobNoError, ARexJobInternalError, ARexJobConfigurationError, ARexJobDescriptionUnsupportedError,
  ARexJobDescriptionMissingError, ARexJobDescriptionSyntaxError, ARexJobDescriptionLogicalError
}

Functions

static const std::string BES_FACTORY_ACTIONS_BASE_URL ("http://schemas.ggf.org/bes/2006/08/bes-factory/BESFactoryPortType/")
static const std::string BES_FACTORY_NPREFIX ("bes-factory")
static const std::string BES_FACTORY_NAMESPACE ("http://schemas.ggf.org/bes/2006/08/bes-factory")
static const std::string BES_MANAGEMENT_ACTIONS_BASE_URL ("http://schemas.ggf.org/bes/2006/08/bes-management/BESManagementPortType/")
static const std::string BES_MANAGEMENT_NPREFIX ("bes-management")
static const std::string BES_MANAGEMENT_NAMESPACE ("http://schemas.ggf.org/bes/2006/08/bes-management")
static const std::string BES_ARC_NPREFIX ("a-rex")
static const std::string BES_ARC_NAMESPACE ("http://www.nordugrid.org/schemas/a-rex")
static const std::string BES_GLUE_NPREFIX ("glue")
static const std::string BES_GLUE_NAMESPACE ("http://schemas.ogf.org/glue/2008/05/spec_2.0_d41_r01")
static Arc::XMLNode BESFactoryResponse (Arc::PayloadSOAP &res, const char *opname)
static Arc::XMLNode BESManagementResponse (Arc::PayloadSOAP &res, const char *opname)
static Arc::XMLNode BESARCResponse (Arc::PayloadSOAP &res, const char *opname)
static Arc::Pluginget_service (Arc::PluginArgument *arg)
static std::string GetPath (std::string url)
static std::string GetPath (Arc::Message &inmsg, std::string &base)
static void information_collector_starter (void *arg)
Arc::Logger ConfigLogger (Arc::Logger::getRootLogger(),"Config")
Config ReadConfig (std::istream &is)
 Read configuration from input stream trying all known formats.
Config ReadConfig (const std::string &filename)
 Read configuration from file trying all known formats.
static void XmlErrorHandler (void *, const char *)
static const std::string BES_FACTORY_FAULT_URL ("http://schemas.ggf.org/bes/2006/08/bes-factory/BESFactoryPortType/Fault")
static void SetFaultResponse (Arc::SOAPFault &fault)
static Arc::MCC_Status http_get (Arc::Message &outmsg, const std::string &burl, ARexJob &job, std::string hpath, size_t start, size_t end)
static Arc::Logger logger (Arc::Logger::getRootLogger(),"AREX:GM")
static void * cache_func (void *arg)
static void * wakeup_func (void *arg)
static void kick_func (void *arg)
static void grid_manager (void *arg)
static void GetGlueStates (Arc::XMLNode infodoc, std::map< std::string, std::string > &states)
static bool get_ldif_string (std::istream &ldif, std::string &str)
static void strtolower (std::string &str)
static void trim (std::string &str)
static bool split_ldif_path (const std::string &str, std::list< std::pair< std::string, std::string > > &path)
static bool compare_paths (const std::list< std::pair< std::string, std::string > > &path1, const std::list< std::pair< std::string, std::string > > &path2, int size)
static Arc::XMLNode path_to_XML (const std::list< std::pair< std::string, std::string > > &path, Arc::XMLNode node)
static void reduce_name (std::string &name, Arc::XMLNode x)
static void reduce_names (Arc::XMLNode x)
static void reduce_prefix (std::string &prefix)
bool LDIFtoXML (std::istream &ldif, const std::string &ldif_base, Arc::XMLNode xml)
static void split (const std::string &str, const std::string delim, Arc::XMLNode &root, const std::string &name)
static int open_file_read (const char *filename)
static int open_file_write (const char *filename)
Arc::MessagePayloadnewFileRead (const char *filename, Arc::PayloadRawInterface::Size_t start, Arc::PayloadRawInterface::Size_t end)
Arc::MessagePayloadnewFileRead (int h, Arc::PayloadRawInterface::Size_t start, Arc::PayloadRawInterface::Size_t end)
static Arc::MCC_Status http_put (ARexJob &job, const std::string &hpath, Arc::Logger &logger, Arc::PayloadStreamInterface &stream)
static Arc::MCC_Status http_put (ARexJob &job, const std::string &hpath, Arc::Logger &logger, Arc::PayloadRawInterface &buf)
static bool write_file (int h, char *buf, size_t size)
void convertActivityStatus (const std::string &gm_state, std::string &bes_state, std::string &arex_state, bool failed, bool pending)
void addActivityStatus (Arc::XMLNode pnode, const std::string &gm_state, const std::string &glue_state, bool failed, bool pending)

Variables

Arc::Logger ConfigLogger

Class Documentation

struct ARex::sleep_st

Definition at line 106 of file grid_manager.cpp.

Collaboration diagram for ARex::sleep_st:
Class Members
pthread_cond_t * sleep_cond
pthread_mutex_t * sleep_mutex
CommFIFO * timeout
struct ARex::args_st

Definition at line 130 of file grid_manager.cpp.

Class Members
int argc
char ** argv

Enumeration Type Documentation

Enumerator:
ARexJobNoError 
ARexJobInternalError 
ARexJobConfigurationError 
ARexJobDescriptionUnsupportedError 
ARexJobDescriptionMissingError 
ARexJobDescriptionSyntaxError 
ARexJobDescriptionLogicalError 

Definition at line 46 of file job.h.

             {
  ARexJobNoError,
  ARexJobInternalError, // Failed during some internal operation - like writing some file
  ARexJobConfigurationError, // Problem detected which can be fixed by adjusting configuration of service
  ARexJobDescriptionUnsupportedError, // Job asks for feature or combination not supported by service
  ARexJobDescriptionMissingError, // Job is missing optional but needed for this service element
  ARexJobDescriptionSyntaxError, // Job description is malformed - missing elements, wrong names, etc.
  ARexJobDescriptionLogicalError // Job request otherwise corect has some values out of scope of service
} ARexJobFailure;

Function Documentation

void ARex::addActivityStatus ( Arc::XMLNode  pnode,
const std::string &  gm_state,
const std::string &  glue_state,
bool  failed,
bool  pending 
)

Definition at line 30 of file tools.cpp.

                                                                                                                          {
    std::string bes_state("");
    std::string arex_state("");
    convertActivityStatus(gm_state,bes_state,arex_state,failed,pending);
    Arc::XMLNode state = pnode.NewChild("bes-factory:ActivityStatus");
    state.NewAttribute("state")=bes_state;
    state.NewChild("a-rex:State")=arex_state;
    if(pending) state.NewChild("a-rex:State")="Pending";
    if(!glue_state.empty()) {
      std::string::size_type p = glue_state.find(':');
      if(p != std::string::npos) {
        if(glue_state.substr(0,p) == "INLRMS") {
          // Extrach state of batch system
          state.NewChild("a-rex:LRMSState")=glue_state.substr(p+1);
        };
      };
      state.NewChild("glue:State")=glue_state;
    };
  }

Here is the call graph for this function:

Here is the caller graph for this function:

static const std::string ARex::BES_ARC_NAMESPACE ( "http://www.nordugrid.org/schemas/a-rex"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_ARC_NPREFIX ( "a-rex"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_FACTORY_ACTIONS_BASE_URL ( "http://schemas.ggf.org/bes/2006/08/bes-factory/BESFactoryPortType/"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_FACTORY_FAULT_URL ( "http://schemas.ggf.org/bes/2006/08/bes-factory/BESFactoryPortType/Fault"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_FACTORY_NAMESPACE ( "http://schemas.ggf.org/bes/2006/08/bes-factory"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_FACTORY_NPREFIX ( "bes-factory"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_GLUE_NAMESPACE ( "http://schemas.ogf.org/glue/2008/05/spec_2.0_d41_r01"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_GLUE_NPREFIX ( "glue"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_MANAGEMENT_ACTIONS_BASE_URL ( "http://schemas.ggf.org/bes/2006/08/bes-management/BESManagementPortType/"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_MANAGEMENT_NAMESPACE ( "http://schemas.ggf.org/bes/2006/08/bes-management"  ) [static]

Here is the caller graph for this function:

static const std::string ARex::BES_MANAGEMENT_NPREFIX ( "bes-management"  ) [static]

Here is the caller graph for this function:

static Arc::XMLNode ARex::BESARCResponse ( Arc::PayloadSOAP res,
const char *  opname 
) [static]

Definition at line 61 of file arex.cpp.

                                                                         {
  Arc::XMLNode response = res.NewChild(BES_ARC_NPREFIX + ":" + opname + "Response");
  return response;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Arc::XMLNode ARex::BESFactoryResponse ( Arc::PayloadSOAP res,
const char *  opname 
) [static]

Definition at line 49 of file arex.cpp.

                                                                             {
  Arc::XMLNode response = res.NewChild(BES_FACTORY_NPREFIX + ":" + opname + "Response");
  Arc::WSAHeader(res).Action(BES_FACTORY_ACTIONS_BASE_URL + opname + "Response");
  return response;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Arc::XMLNode ARex::BESManagementResponse ( Arc::PayloadSOAP res,
const char *  opname 
) [static]

Definition at line 55 of file arex.cpp.

                                                                                {
  Arc::XMLNode response = res.NewChild(BES_MANAGEMENT_NPREFIX + ":" + opname + "Response");
  Arc::WSAHeader(res).Action(BES_MANAGEMENT_ACTIONS_BASE_URL + opname + "Response");
  return response;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* ARex::cache_func ( void *  arg) [static]

Definition at line 43 of file grid_manager.cpp.

                                   {
  const JobUsers* users = (const JobUsers*)arg;
  Arc::Run *proc = NULL;
  JobUser gmuser(getuid()); // Cleaning should run under the GM user 
  
  // run cache cleaning periodically 
  for(;;) {
    // go through each user and clean their caches. One user is processed per clean period
    for (JobUsers::const_iterator cacheuser = users->begin(); cacheuser != users->end(); ++cacheuser) {
      int exit_code = -1;
      // if previous process has not finished
      if(proc != NULL) {  
        if(!(proc->Running())) {
          exit_code=proc->Result();
          delete proc;
          proc=NULL;
        };
      };
      if(proc == NULL) { // previous already exited
        CacheConfig * cache_info = cacheuser->CacheParams();
        if (!cache_info->cleanCache()) continue;
        
        // get the cache dirs
        std::vector<std::string> cache_info_dirs = cache_info->getCacheDirs();

        // in arc.conf % of used space is given, but cleanbyage uses % of free space
        std::string minfreespace = Arc::tostring(100-cache_info->getCacheMax());
        std::string maxfreespace = Arc::tostring(100-cache_info->getCacheMin());  

        // set log file location - controldir/job.cache-clean.errors
        // TODO: use GM log?
        gmuser.SetControlDir(cacheuser->ControlDir()); // Should this requirement be removed ?
        int argc=0;
        char* args[7+cache_info_dirs.size()+1];
        
        // do cache-clean -h for explanation of options
        std::string cmd = nordugrid_libexec_loc() + "/cache-clean";
        args[argc++]=(char*)cmd.c_str();
        args[argc++]=(char*)"-m";
        args[argc++]=(char*)minfreespace.c_str();
        args[argc++]=(char*)"-M";
        args[argc++]=(char*)maxfreespace.c_str();
        args[argc++]=(char*)"-D";
        args[argc++]=(char*)cache_info->getLogLevel().c_str();
        std::vector<std::string> cache_dirs;
        // have to loop over twice to avoid repeating the same pointer in args
        for (std::vector<std::string>::iterator i = cache_info_dirs.begin(); i != cache_info_dirs.end(); i++) {
          cache_dirs.push_back(i->substr(0, i->find(" ")));
        }
        for (std::vector<std::string>::iterator i = cache_dirs.begin(); i != cache_dirs.end(); i++) {
          args[argc++]=(char*)(*i).c_str();
        }
        args[argc]=NULL;
        if(!RunParallel::run(gmuser,"cache-clean",args,&proc,false,false)) {
          logger.msg(Arc::ERROR,"Failed to run cache cleanup script: %s", cmd);
        };
      };
      for(unsigned int t=CACHE_CLEAN_PERIOD;t;) t=sleep(t);
    };
  };
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool ARex::compare_paths ( const std::list< std::pair< std::string, std::string > > &  path1,
const std::list< std::pair< std::string, std::string > > &  path2,
int  size 
) [static]

Definition at line 52 of file LDIFtoXML.cpp.

                                                                                                                                            {
  std::list<std::pair<std::string,std::string> >::const_iterator i1 = path1.begin();
  std::list<std::pair<std::string,std::string> >::const_iterator i2 = path2.begin();
  for(;size>0;--size) {
    if((i1 == path1.end()) && (i2 == path2.end())) break;
    if(i1 == path1.end()) return false;
    if(i2 == path2.end()) return false;
    if(i1->first != i2->first) return false;
    if(i1->second != i2->second) return false;
    ++i1; ++i2;
  };
  return true;
}

Here is the caller graph for this function:

Arc::Logger ARex::ConfigLogger ( Arc::Logger::  getRootLogger(),
"Config"   
)
void ARex::convertActivityStatus ( const std::string &  gm_state,
std::string &  bes_state,
std::string &  arex_state,
bool  failed,
bool  pending 
)

Definition at line 5 of file tools.cpp.

                                                                                                                            {
    if(gm_state == "ACCEPTED") {
      bes_state="Pending"; arex_state="Accepted";
    } else if(gm_state == "PREPARING") {
      bes_state="Running"; arex_state=(!pending)?"Preparing":"Prepared";
    } else if(gm_state == "SUBMIT") {
      bes_state="Running"; arex_state="Submitting";
    } else if(gm_state == "INLRMS") {
      bes_state="Running"; arex_state=(!pending)?"Executing":"Executed";
    } else if(gm_state == "FINISHING") {
      bes_state="Running"; arex_state="Finishing";
    } else if(gm_state == "FINISHED") {
      if(!failed) {
        bes_state="Finished"; arex_state="Finished";
      } else {
        bes_state="Failed"; arex_state="Failed";
      };
    } else if(gm_state == "DELETED") {
      // AFAIR failed is not avialable anymore.
      bes_state=(!failed)?"Finished":"Failed"; arex_state="Deleted";
    } else if(gm_state == "CANCELING") {
      bes_state="Running"; arex_state="Killing";
    };
  }

Here is the caller graph for this function:

static bool ARex::get_ldif_string ( std::istream &  ldif,
std::string &  str 
) [static]

Definition at line 9 of file LDIFtoXML.cpp.

                                                             {
  while(ldif) {
    getline(ldif,str);
    if(str.empty()) continue;
    if(str[0] == '#') continue;
    return true;
  };
  return false;
}

Here is the caller graph for this function:

static Arc::Plugin* ARex::get_service ( Arc::PluginArgument arg) [static]

Definition at line 68 of file arex.cpp.

                                                      {
    Arc::ServicePluginArgument* srvarg =
            arg?dynamic_cast<Arc::ServicePluginArgument*>(arg):NULL;
    if(!srvarg) return NULL;
    ARexService* arex = new ARexService((Arc::Config*)(*srvarg));
    if(!*arex) { delete arex; arex=NULL; };
    return arex;
}
static void ARex::GetGlueStates ( Arc::XMLNode  infodoc,
std::map< std::string, std::string > &  states 
) [static]

Definition at line 118 of file information_collector.cpp.

                                                                                  {
  std::string path = "Domains/AdminDomain/Services/ComputingService/ComputingEndpoint/ComputingActivities/ComputingActivity";
  // Obtaining all job descriptions
  Arc::XMLNodeList nodes = infodoc.Path(path);
  // Pulling ids and states
  for(Arc::XMLNodeList::iterator node = nodes.begin();node!=nodes.end();++node) {
    // Exract ID of job
    std::string id = (*node)["IDFromEndpoint"];
    if(id.empty()) id = (std::string)((*node)["ID"]);
    if(id.empty()) continue;
    std::string::size_type p = id.rfind('/');
    if(p != std::string::npos) id.erase(0,p+1);
    if(id.empty()) continue;
    Arc::XMLNode state_node = (*node)["State"];
    for(;(bool)state_node;++state_node) {
      std::string state  = (std::string)state_node;
      if(state.empty()) continue;
      // Look for nordugrid prefix
      if(strncmp("nordugrid:",state.c_str(),10) == 0) {
        // Remove prefix
        state.erase(0,10);
        // Store state under id
        states[id] = state;
      };
    };
  };
}

Here is the call graph for this function:

Here is the caller graph for this function:

static std::string ARex::GetPath ( std::string  url) [static]

Definition at line 122 of file arex.cpp.

                                       {
  std::string::size_type ds, ps;
  ds=url.find("//");
  if (ds==std::string::npos)
    ps=url.find("/");
  else
    ps=url.find("/", ds+2);
  if (ps==std::string::npos)
    return "";
  else
    return url.substr(ps);
}

Here is the caller graph for this function:

static std::string ARex::GetPath ( Arc::Message inmsg,
std::string &  base 
) [static]

Definition at line 224 of file arex.cpp.

                                                            {
  base = inmsg.Attributes()->get("HTTP:ENDPOINT");
  Arc::AttributeIterator iterator = inmsg.Attributes()->getAll("PLEXER:EXTENSION");
  std::string path;
  if(iterator.hasMore()) {
    // Service is behind plexer
    path = *iterator;
    if(base.length() > path.length()) base.resize(base.length()-path.length());
  } else {
    // Standalone service
    path=Arc::URL(base).Path();
    base.resize(0);
  };
  return path;
}

Here is the call graph for this function:

static void ARex::grid_manager ( void *  arg) [static]

Definition at line 135 of file grid_manager.cpp.

                                    {
  const char* config_filename = (const char*)arg;
  if(!arg) return;
  unsigned int clean_first_level=0;
  // int n;
  // int argc = ((args_st*)arg)->argc;
  // char** argv = ((args_st*)arg)->argv;
  setpgid(0,0);
  opterr=0;
  if(config_filename) nordugrid_config_loc(config_filename);

  logger.msg(Arc::INFO,"Starting grid-manager thread");
  Daemon daemon;
  // Only supported option now is -c
  /*
  while((n=daemon.getopt(argc,argv,"hvC:c:")) != -1) {
    switch(n) {
      case ':': { logger.msg(Arc::ERROR,"Missing argument"); return; };
      case '?': { logger.msg(Arc::ERROR,"Unrecognized option: %s",(char)optopt); return; };
      case '.': { return; };
      case 'h': {
        std::cout<<"grid-manager [-C clean_level] [-v] [-h] [-c configuration_file] "<<daemon.short_help()<<std::endl;
         return;
      };
      case 'v': {
        std::cout<<"grid-manager: version "<<VERSION<<std::endl;
        return;
      };
      case 'C': {
        if(sscanf(optarg,"%u",&clean_first_level) != 1) {
          logger.msg(Arc::ERROR,"Wrong clean level");
          return;
        };
      }; break;
      case 'c': {
        nordugrid_config_loc=optarg;
      }; break;
      default: { logger.msg(Arc::ERROR,"Option processing error"); return; };
    };
  };
  */

  JobUsers users;
  std::string my_username("");
  uid_t my_uid=getuid();
  JobUser *my_user = NULL;
  if(!read_env_vars()) {
    logger.msg(Arc::FATAL,"Can't initialize runtime environment - EXITING"); return;
  };
  
  /* recognize itself */
  {
    struct passwd pw_;
    struct passwd *pw;
    char buf[BUFSIZ];
    getpwuid_r(my_uid,&pw_,buf,BUFSIZ,&pw);
    if(pw != NULL) { my_username=pw->pw_name; };
  };
  if(my_username.length() == 0) {
    logger.msg(Arc::FATAL,"Can't recognize own username - EXITING"); return;
  };
  my_user = new JobUser(my_username);
  if(!configure_serviced_users(users,my_uid,my_username,*my_user,&daemon)) {
    logger.msg(Arc::INFO,"Used configuration file %s",nordugrid_config_loc());
    logger.msg(Arc::FATAL,"Error processing configuration - EXITING"); return;
  };
  if(users.size() == 0) {
    logger.msg(Arc::FATAL,"No suitable users found in configuration - EXITING"); return;
  };

  //daemon.logfile(DEFAULT_LOG_FILE);
  //daemon.pidfile(DEFAULT_PID_FILE);
  //if(daemon.daemon() != 0) {
  //  perror("Error - daemonization failed");
  //  exit(1);
  //}; 
  logger.msg(Arc::INFO,"Used configuration file %s",nordugrid_config_loc());
  print_serviced_users(users);

  //unsigned int wakeup_period = JobsList::WakeupPeriod();
  CommFIFO wakeup_interface;
  pthread_t wakeup_thread;
  pthread_t cache_thread;
  time_t hard_job_time; 
  pthread_cond_t sleep_cond = PTHREAD_COND_INITIALIZER;
  pthread_mutex_t sleep_mutex = PTHREAD_MUTEX_INITIALIZER;
  sleep_st wakeup_h;
  wakeup_h.sleep_cond=&sleep_cond;
  wakeup_h.sleep_mutex=&sleep_mutex;
  wakeup_h.timeout=&wakeup_interface;
  for(JobUsers::iterator i = users.begin();i!=users.end();++i) {
    wakeup_interface.add(*i);
  };
  wakeup_interface.timeout(JobsList::WakeupPeriod());

  // Prepare signal handler(s). Must be done after fork/daemon and preferably
  // before any new thread is started. 
  //# RunParallel run(&sleep_cond);
  //# if(!run.is_initialized()) {
  //#   logger.msg(Arc::ERROR,"Error - initialization of signal environment failed");
  //#   goto exit;
  //# };

  // I hope nothing till now used Globus

  // It looks like Globus screws signal setup somehow
  //# run.reinit(false);

  /* start timer thread - wake up every 2 minutes */
  if(pthread_create(&wakeup_thread,NULL,&wakeup_func,&wakeup_h) != 0) {
    logger.msg(Arc::ERROR,"Failed to start new thread"); return;
  };
  RunParallel::kicker(&kick_func,&wakeup_h);
  if(clean_first_level) {
    bool clean_finished = false;
    bool clean_active = false;
    bool clean_junk = false;
    if(clean_first_level >= 1) {
      clean_finished=true;
      if(clean_first_level >= 2) {
        clean_active=true;
        if(clean_first_level >= 3) {
          clean_junk=true;
        };
      };
    };
    for(;;) { 
      bool cleaned_all=true;
      for(JobUsers::iterator user = users.begin();user != users.end();++user) {
        size_t njobs = user->get_jobs()->size();
        user->get_jobs()->ScanNewJobs(false);
        if(user->get_jobs()->size() == njobs) break;
        cleaned_all=false;
        if(!(user->get_jobs()->DestroyJobs(clean_finished,clean_active)))  {
          logger.msg(Arc::WARNING,"Not all jobs are cleaned yet");
          sleep(10); 
          logger.msg(Arc::WARNING,"Trying again");
        };
        kill(getpid(),SIGCHLD);  /* make sure no child is missed */
      };
      if(cleaned_all) {
        if(clean_junk && clean_active && clean_finished) {  
          /* at the moment cleaning junk means cleaning all the files in 
             session and control directories */
          for(JobUsers::iterator user=users.begin();user!=users.end();++user) {
            std::list<FileData> flist;
            for(std::vector<std::string>::const_iterator i = user->SessionRoots().begin(); i != user->SessionRoots().end(); i++) {
              logger.msg(Arc::INFO,"Cleaning all files in directory %s", *i);
              delete_all_files(*i,flist,true);
            }
            logger.msg(Arc::INFO,"Cleaning all files in directory %s", user->ControlDir());
            delete_all_files(user->ControlDir(),flist,true);
          };
        };
        break;
      };
    };
    logger.msg(Arc::INFO,"Jobs cleaned");
  };
  // check if cleaning is enabled for any user, if so activate cleaning thread
  for (JobUsers::const_iterator cacheuser = users.begin(); cacheuser != users.end(); ++cacheuser) {
    if (cacheuser->CacheParams() && cacheuser->CacheParams()->cleanCache()) {
      if(pthread_create(&cache_thread,NULL,&cache_func,(void*)(&users))!=0) {
        logger.msg(Arc::INFO,"Failed to start new thread: cache won't be cleaned");
      }
      break;
    }
  }
  /* create control and session directories */
  for(JobUsers::iterator user = users.begin();user != users.end();++user) {
    user->CreateDirectories();
  };
  /* main loop - forewer */
  logger.msg(Arc::INFO,"Starting jobs' monitoring");
  hard_job_time = time(NULL) + HARD_JOB_PERIOD;
  for(;;) { 
    users.run_helpers();
    job_log.RunReporter(users);
    my_user->run_helpers();
    bool hard_job = time(NULL) > hard_job_time;
    for(JobUsers::iterator user = users.begin();user != users.end();++user) {
      /* look for new jobs */
      user->get_jobs()->ScanNewJobs(hard_job);
      /* process know jobs */
      user->get_jobs()->ActJobs(hard_job);
    };
    if(hard_job) hard_job_time = time(NULL) + HARD_JOB_PERIOD;
    pthread_mutex_lock(&sleep_mutex);
    pthread_cond_wait(&sleep_cond,&sleep_mutex);
    pthread_mutex_unlock(&sleep_mutex);
//#    if(run.was_hup()) {
//#      logger.msg(Arc::INFO,"SIGHUP detected");
//#//      if(!configure_serviced_users(users,my_uid,my_username,*my_user)) {
//#//        std::cout<<"Error processing configuration"<<std::endl; goto exit;
//#//      };
//#    }
//#    else {
      logger.msg(Arc::DEBUG,"Waking up");
//#    };
  };
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Arc::MCC_Status ARex::http_get ( Arc::Message outmsg,
const std::string &  burl,
ARexJob &  job,
std::string  hpath,
size_t  start,
size_t  end 
) [static]

Definition at line 103 of file get.cpp.

                                                                                                                             {
Arc::Logger::rootLogger.msg(Arc::VERBOSE, "http_get: start=%u, end=%u, burl=%s, hpath=%s", (unsigned int)start, (unsigned int)end, burl, hpath);
  if(!hpath.empty()) if(hpath[0] == '/') hpath=hpath.substr(1);
  if(!hpath.empty()) if(hpath[hpath.length()-1] == '/') hpath.resize(hpath.length()-1);
  std::string joblog = job.LogDir();
  if(!joblog.empty()) {
    if((strncmp(joblog.c_str(),hpath.c_str(),joblog.length()) == 0)  && 
       ((hpath[joblog.length()] == '/') || (hpath[joblog.length()] == 0))) {
      hpath.erase(0,joblog.length()+1);
      if(hpath.empty()) {
        std::list<std::string> logs = job.LogFiles();
        std::string html;
        html="<HTML>\r\n<HEAD>\r\n<TITLE>ARex: Job Logs</TITLE>\r\n</HEAD>\r\n<BODY>\r\n<UL>\r\n";
        for(std::list<std::string>::iterator l = logs.begin();l != logs.end();++l) {
          if(strncmp(l->c_str(),"proxy",5) == 0) continue;
          std::string line = "<LI><I>file</I> <A HREF=\"";
          line+=burl+"/"+joblog+"/"+(*l);
          line+="\">";
          line+=*l;
          line+="</A> - log file\r\n";
          html+=line;
        };
        html+="</UL>\r\n</BODY>\r\n</HTML>";
        Arc::PayloadRaw* buf = new Arc::PayloadRaw;
        if(buf) buf->Insert(html.c_str(),0,html.length());
        outmsg.Payload(buf);
        outmsg.Attributes()->set("HTTP:content-type","text/html");
        return Arc::MCC_Status(Arc::STATUS_OK);
      } else {
        int file = job.OpenLogFile(hpath);
        if(file != -1) {
          Arc::MessagePayload* h = newFileRead(file,start,end);
          outmsg.Payload(h);
          outmsg.Attributes()->set("HTTP:content-type","application/octet-stream");
          return Arc::MCC_Status(Arc::STATUS_OK);
        };
        return Arc::MCC_Status();
      };
    };
  };
  Glib::Dir* dir = job.OpenDir(hpath);
  if(dir) {
    // Directory - html with file list
    std::string file;
    std::string html;
    html="<HTML>\r\n<HEAD>\r\n<TITLE>ARex: Job</TITLE>\r\n</HEAD>\r\n<BODY>\r\n<UL>\r\n";
    std::string furl = burl;
    if(!hpath.empty()) furl+="/"+hpath;
    std::string path = job.GetFilePath(hpath);
    for(;;) {
      file=dir->read_name();
      if(file.empty()) break;
      if(file == ".") continue;
      if(file == "..") continue;
      std::string fpath = path+"/"+file;
      struct stat st;
      if(lstat(fpath.c_str(),&st) == 0) {
        if(S_ISREG(st.st_mode)) {
          std::string line = "<LI><I>file</I> <A HREF=\"";
          line+=furl+"/"+file;
          line+="\">";
          line+=file;
          line+="</A> - "+Arc::tostring(st.st_size)+" bytes"+"\r\n";
          html+=line;
        } else if(S_ISDIR(st.st_mode)) {
          std::string line = "<LI><I>dir</I> <A HREF=\"";
          line+=furl+"/"+file+"/";
          line+="\">";
          line+=file;
          line+="</A>\r\n";
          html+=line;
        };
      } else {
        std::string line = "<LI><I>unknown</I> <A HREF=\"";
        line+=furl+"/"+file;
        line+="\">";
        line+=file;
        line+="</A>\r\n";
        html+=line;
      };
    };
    if((hpath.empty()) && (!joblog.empty())) {
      std::string line = "<LI><I>dir</I> <A HREF=\"";
      line+=furl+"/"+joblog;
      line+="\">";
      line+=joblog;
      line+="</A> - log directory\r\n";
      html+=line;
    };
    html+="</UL>\r\n</BODY>\r\n</HTML>";
    Arc::PayloadRaw* buf = new Arc::PayloadRaw;
    if(buf) buf->Insert(html.c_str(),0,html.length());
    outmsg.Payload(buf);
    outmsg.Attributes()->set("HTTP:content-type","text/html");
    delete dir;
    return Arc::MCC_Status(Arc::STATUS_OK);
  };
  int file = job.OpenFile(hpath,true,false);
  if(file != -1) {
    // File 
    Arc::MessagePayload* h = newFileRead(file,start,end);
    outmsg.Payload(h);
    outmsg.Attributes()->set("HTTP:content-type","application/octet-stream");
    return Arc::MCC_Status(Arc::STATUS_OK);
  };
  // Can't process this path
  // offset=0; size=0;
  return Arc::MCC_Status();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Arc::MCC_Status ARex::http_put ( ARexJob &  job,
const std::string &  hpath,
Arc::Logger logger,
Arc::PayloadStreamInterface stream 
) [static]

Definition at line 70 of file put.cpp.

                                                                                                                       {
  // TODO: Use memory mapped file to minimize number of in memory copies
  // File 
  const int bufsize = 1024*1024;
  int h = job.CreateFile(hpath.c_str());
  if(h == -1) {
    // TODO: report something
    logger.msg(Arc::ERROR, "Put: failed to create file %s for job %s - %s", hpath, job.ID(), job.Failure());
    return Arc::MCC_Status();
  };
  int pos = stream.Pos(); 
  if(lseek(h,pos,SEEK_SET) != pos) {
    std::string err = Arc::StrError();
    ::close(h);
    logger.msg(Arc::ERROR, "Put: failed to set position of file %s for job %s to %i - %s", hpath, job.ID(), pos, err);
    return Arc::MCC_Status();
  };
  char* buf = new char[bufsize];
  if(!buf) {
    ::close(h);
    logger.msg(Arc::ERROR, "Put: failed to allocate memory for file %s in job %s", hpath, job.ID());
    return Arc::MCC_Status();
  };
  for(;;) {
    int size = bufsize;
    if(!stream.Get(buf,size)) break;
    if(!write_file(h,buf,size)) {
      std::string err = Arc::StrError();
      delete[] buf; ::close(h);
      logger.msg(Arc::ERROR, "Put: failed to write to file %s for job %s - %s", hpath, job.ID(), err);
      return Arc::MCC_Status();
    };
  };
  delete[] buf; ::close(h);
  return Arc::MCC_Status(Arc::STATUS_OK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Arc::MCC_Status ARex::http_put ( ARexJob &  job,
const std::string &  hpath,
Arc::Logger logger,
Arc::PayloadRawInterface buf 
) [static]

Definition at line 107 of file put.cpp.

                                                                                                                 {
  // File 
  int h = job.CreateFile(hpath.c_str());
  if(h == -1) {
    // TODO: report something
    logger.msg(Arc::ERROR, "Put: failed to create file %s for job %s - %s", hpath, job.ID(), job.Failure());
    return Arc::MCC_Status();
  };
  for(int n = 0;;++n) {
    char* sbuf = buf.Buffer(n);
    if(sbuf == NULL) break;
    off_t offset = buf.BufferPos(n);
    size_t size = buf.BufferSize(n);
    if(size > 0) {
      off_t o = lseek(h,offset,SEEK_SET);
      if(o != offset) {
        ::close(h);
        return Arc::MCC_Status();
      };
      if(!write_file(h,sbuf,size)) {
        ::close(h);
        return Arc::MCC_Status();
      };
    };
  };
  ::close(h);
  return Arc::MCC_Status(Arc::STATUS_OK);
}

Here is the call graph for this function:

static void ARex::information_collector_starter ( void *  arg) [static]

Definition at line 455 of file arex.cpp.

                                                     {
  if(!arg) return;
  ((ARexService*)arg)->InformationCollector();
}

Here is the caller graph for this function:

static void ARex::kick_func ( void *  arg) [static]

Definition at line 123 of file grid_manager.cpp.

                                 {
  sleep_st* s = (sleep_st*)arg;
  pthread_mutex_lock(s->sleep_mutex);
  pthread_cond_signal(s->sleep_cond);
  pthread_mutex_unlock(s->sleep_mutex);
}

Here is the caller graph for this function:

bool ARex::LDIFtoXML ( std::istream &  ldif,
const std::string &  ldif_base,
Arc::XMLNode  xml 
)

Definition at line 130 of file LDIFtoXML.cpp.

                                                                           {
  std::list<std::pair<std::string,std::string> > base;
  split_ldif_path(ldif_base,base);
  std::string str;
  if(!get_ldif_string(ldif,str)) return true;
  for(;;) { // LDIF processing loop
    for(;;) { // Looking for dn:
      if(strncasecmp(str.c_str(),"dn:",3) == 0) break;
      if(!get_ldif_string(ldif,str)) { reduce_names(xml); return true; };
    };
    str.replace(0,3,"");
    std::list<std::pair<std::string,std::string> > dn;
    split_ldif_path(str,dn);
    if(base.size() > dn.size()) continue; // Above base
    if(!compare_paths(base,dn,base.size())) continue; // Wrong base
    // Removing base
    for(int n = 0;n<base.size();++n) dn.erase(dn.begin());
    Arc::XMLNode x = path_to_XML(dn,xml);
    if(!x) return false;
    Arc::NS ns;
    for(;;) { // Reading ObjectClass elements
      if(!get_ldif_string(ldif,str)) { reduce_names(xml); return true; };
      if(strncasecmp(str.c_str(),"objectclass:",12) != 0) break;
      // Converting ObjectClass into namespace
      str.replace(0,12,"");
      trim(str);
      std::string prefix=str;
      reduce_prefix(prefix);
      for(int n = 0;;++n) {
        if(ns.find(prefix+Arc::tostring(n)) == ns.end()) {
          ns[prefix+Arc::tostring(n)]="urn:"+str;
          break;
        };
      };
    };
    x.Namespaces(ns);
    // Read name:value data
    for(;;) {
      if(strncasecmp(str.c_str(),"dn:",3) == 0) break;
      std::string::size_type p = str.find(':');
      std::string name;
      std::string value;
      if(p == std::string::npos) {
        name=str;
      } else {
        name=str.substr(0,p);
        value=str.substr(p+1);
      };
      trim(name); trim(value);
      reduce_name(name,x);
      x.NewChild(name)=value; // TODO: XML escaping for value
      if(!get_ldif_string(ldif,str)) { reduce_names(xml); return true; };
    };
  };
  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Arc::Logger ARex::logger ( Arc::Logger::  getRootLogger(),
"AREX:GM"   
) [static]

Here is the caller graph for this function:

Definition at line 188 of file PayloadFile.cpp.

                                                                                                                         {
  int h = open_file_read(filename);
  return newFileRead(h,start,end);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 193 of file PayloadFile.cpp.

                                                                                                          {
#ifndef WIN32 
  struct stat st;
  if(fstat(h,&st) != 0) return NULL;
  if(st.st_size > PayloadBigFile::Threshold()) {
    PayloadBigFile* f = new PayloadBigFile(h,start,end);
    if(!*f) { delete f; return NULL; };
    return f;
  } else {
    PayloadFile* f = new PayloadFile(h,start,end);
    if(!*f) { delete f; return NULL; };
    return f;
  };
#else
  PayloadBigFile* f = new PayloadBigFile(h,start,end);
  if(!*f) { delete f; return NULL; };
  return f;
#endif
}

Here is the call graph for this function:

static int ARex::open_file_read ( const char *  filename) [static]

Definition at line 126 of file PayloadFile.cpp.

                                                {
  return ::open(filename,O_RDONLY);
}

Here is the caller graph for this function:

static int ARex::open_file_write ( const char *  filename) [static]

Definition at line 130 of file PayloadFile.cpp.

                                                 {
  return ::open(filename,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR);
}
static Arc::XMLNode ARex::path_to_XML ( const std::list< std::pair< std::string, std::string > > &  path,
Arc::XMLNode  node 
) [static]

Definition at line 66 of file LDIFtoXML.cpp.

                                                                                                  {
  Arc::XMLNode cur = node;
  std::list<std::pair<std::string,std::string> >::const_iterator i = path.begin();
  for(;i!=path.end();++i) {
    Arc::XMLNode n = cur[i->first];
    Arc::XMLNode nn;
    for(int num = 0;;++num) {
      nn=n[num];
      if(!nn) break;
      if((std::string)(nn.Attribute("name")) == i->second) break;
    };
    if(!nn) {
      nn=cur.NewChild(i->first);
      nn.NewAttribute("name")=i->second;
    };
    cur=nn;
  };
  return cur;  
}

Here is the call graph for this function:

Here is the caller graph for this function:

Config ARex::ReadConfig ( std::istream &  is)

Read configuration from input stream trying all known formats.

Definition at line 149 of file configcore.cpp.

                                  {

       try {
              is.seekg(0, std::ios::beg);
              return XMLConfig().Read(is);
       }
       catch(ConfigError) {
              is.clear();
       }
       try {
              is.seekg(0, std::ios::beg);
              return NGConfig().Read(is);
       }
       catch(ConfigError) {
              is.clear();
       }
       throw ConfigError("Unknown configuration format");
}

Here is the call graph for this function:

Here is the caller graph for this function:

Config ARex::ReadConfig ( const std::string &  filename)

Read configuration from file trying all known formats.

Definition at line 169 of file configcore.cpp.

                                             {

       static std::map<std::string, Config> configcache;

       if (configcache.find(filename) != configcache.end()) {
              ConfigLogger.msg(Arc::DEBUG, "Using cached configuration: %s", filename);
              return configcache[filename];
       }

       ConfigLogger.msg(Arc::DEBUG, "Reading configuration file: %s", filename);

       std::ifstream is(filename.c_str());
       Config conf = ReadConfig(is);
       is.close();
       configcache[filename] = conf;
       return conf;
}

Here is the call graph for this function:

static void ARex::reduce_name ( std::string &  name,
Arc::XMLNode  x 
) [static]

Definition at line 86 of file LDIFtoXML.cpp.

                                                      {
  std::string::size_type p = std::string::npos;
  for(;;) {
    p=name.rfind('-',p);
    if(p == std::string::npos) break;
    std::string urn = "urn:"+name.substr(0,p);
    std::string prefix = x.NamespacePrefix(urn.c_str());
    if(!prefix.empty()) {
      name=prefix+":"+name.substr(p+1);
      break;
    };
    --p;
  };
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ARex::reduce_names ( Arc::XMLNode  x) [static]

Definition at line 101 of file LDIFtoXML.cpp.

                                       {
  if(x.Size() == 0) return;
  std::string name = x.Name();
  reduce_name(name,x);
  x.Name(name.c_str());
  for(int n = 0;;++n) {
    Arc::XMLNode x_ = x.Child(n);
    if(!x_) break;
    reduce_names(x_);
  };
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ARex::reduce_prefix ( std::string &  prefix) [static]

Definition at line 113 of file LDIFtoXML.cpp.

                                             {
  std::string::size_type p = 0;
  p=0;
  for(;p<prefix.length();) {
    std::string::size_type p_ = p;
    for(;p_<prefix.length();++p_) if(prefix[p_] != '-') break;
    if(p!=p_) prefix.replace(p,p_-p,"");
    p_=prefix.find('-',p);
    if(p_ == std::string::npos) {
      prefix.replace(p+1,std::string::npos,"");
    } else {
      prefix.replace(p+1,p_-p,"");
    };
    ++p;
  };
}

Here is the caller graph for this function:

static void ARex::SetFaultResponse ( Arc::SOAPFault &  fault) [static]

Definition at line 37 of file faults.cpp.

                                                  {
  // Fetch top element of SOAP message - should be better way
  Arc::XMLNode fault_node = fault;
  Arc::SOAPEnvelope res(fault_node.Parent().Parent()); // Fault->Body->Envelope
  Arc::WSAHeader(res).Action(BES_FACTORY_FAULT_URL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ARex::split ( const std::string &  str,
const std::string  delim,
Arc::XMLNode root,
const std::string &  name 
) [static]

Definition at line 14 of file JobRecord.cpp.

                                                                                                        {
  std::string::size_type offset = 0;
  std::string::size_type delimIndex = 0;

  delimIndex = str.find(delim, offset);

  while (delimIndex != std::string::npos) {
    root.NewChild(name) = str.substr(offset, delimIndex - offset);
    offset += delimIndex - offset + delim.length();
    delimIndex = str.find(delim, offset);
  }

  root.NewChild(name) = str.substr(offset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool ARex::split_ldif_path ( const std::string &  str,
std::list< std::pair< std::string, std::string > > &  path 
) [static]

Definition at line 35 of file LDIFtoXML.cpp.

                                                                                               {
  std::string::size_type cur = 0;
  while(true) {
    std::string::size_type p = str.find('=',cur);
    if(p == std::string::npos) return true;
    std::string name = str.substr(cur,p-cur);
    std::string::size_type e = str.find(',',p);
    if(e == std::string::npos) e = str.length();
    std::string val = str.substr(p+1,e-p-1);
    trim(name); trim(val);
    strtolower(name); strtolower(val);
    path.push_front(std::pair<std::string,std::string>(name,val));
    cur=e+1;
  };
  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ARex::strtolower ( std::string &  str) [static]

Definition at line 19 of file LDIFtoXML.cpp.

                                       {
  std::string::size_type l = str.length();
  char* s = (char*)(str.c_str());
  for(;l>0;--l,++s) *s=tolower(*s);
}

Here is the caller graph for this function:

static void ARex::trim ( std::string &  str) [static]

Definition at line 25 of file LDIFtoXML.cpp.

                                 {
  std::string::size_type first = str.find_first_not_of(' ');
  if(first == std::string::npos) {
    str.resize(0); return;
  };
  std::string::size_type last = str.find_last_not_of(' ');
  str=str.substr(first,last-first+1);
  return;
}

Here is the caller graph for this function:

static void* ARex::wakeup_func ( void *  arg) [static]

Definition at line 112 of file grid_manager.cpp.

                                    {
  sleep_st* s = (sleep_st*)arg;
  for(;;) {
    s->timeout->wait();
    pthread_mutex_lock(s->sleep_mutex);
    pthread_cond_signal(s->sleep_cond);
    pthread_mutex_unlock(s->sleep_mutex);
  };
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool ARex::write_file ( int  h,
char *  buf,
size_t  size 
) [static]

Definition at line 61 of file put.cpp.

                                                    {
  for(;size>0;) {
    ssize_t l = write(h,buf,size);
    if(l == -1) return false;
    size-=l; buf+=l;
  };
  return true;
}

Here is the caller graph for this function:

static void ARex::XmlErrorHandler ( void *  ,
const char *   
) [static]

Definition at line 17 of file xmlconfig.cpp.

                                                {
       return;
}

Here is the caller graph for this function:


Variable Documentation