Back to index

nordugrid-arc-nox  1.1.0~rc6
gm_jobs.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <cstdio>
00006 #include <fstream>
00007 #include <pwd.h>
00008 
00009 #include <arc/XMLNode.h>
00010 #include <arc/ArcConfig.h>
00011 #include <arc/DateTime.h>
00012 #include <arc/Logger.h>
00013 #include <arc/OptionParser.h>
00014 
00015 #include "jobs/users.h"
00016 #include "conf/conf_file.h"
00017 #include "jobs/plugins.h"
00018 #include "files/info_files.h"
00019 #include "jobs/commfifo.h"
00020 
00021 void get_arex_xml(Arc::XMLNode& arex) {
00022   
00023   Arc::Config cfg(nordugrid_config_loc().c_str());
00024   if (!cfg) return;
00025 
00026   for (int i=0;; i++) {
00027 
00028     Arc::XMLNode node = cfg["Chain"];
00029     node = node["Service"][i];
00030     if (!node)
00031       return;
00032     if (node.Attribute("name") == "a-rex") {
00033       node.New(arex);
00034       return;
00035     }
00036   }
00037 }
00038 
00042 int main(int argc, char* argv[]) {
00043 
00044   // stderr destination for error messages
00045   Arc::LogStream logcerr(std::cerr);
00046   Arc::Logger::getRootLogger().addDestination(logcerr);
00047   Arc::Logger::getRootLogger().setThreshold(Arc::DEBUG);
00048   
00049   Arc::OptionParser options(istring(""),
00050                             istring("gm-jobs displays information on "
00051                                     "current jobs in the system."));
00052   
00053   bool long_list = false;
00054   options.AddOption('l', "longlist",
00055                     istring("display more information on each job"),
00056                     long_list);
00057 
00058   std::string my_username;
00059   options.AddOption('U', "username",
00060                     istring("pretend utility is run by user with given name"),
00061                     istring("name"), my_username);
00062   
00063   int my_uid = getuid();
00064   options.AddOption('u', "userid",
00065                     istring("pretend utility is run by user with given uid"),
00066                     istring("uid"), my_uid);
00067   
00068   std::string conf_file;
00069   options.AddOption('c', "conffile",
00070                     istring("use specified configuration file"),
00071                     istring("file"), conf_file);
00072   
00073   std::string control_dir;
00074   options.AddOption('d', "controldir",
00075                     istring("read information from specified control dir"),
00076                     istring("dir"), control_dir);
00077                     
00078   bool show_share = false;
00079   options.AddOption('s', "showshares",
00080                   istring("print summary of jobs in each transfer share"),
00081                   show_share);
00082 
00083   bool notshow_jobs = false;
00084   options.AddOption('J', "notshowjobs",
00085                   istring("do not print list of jobs"),
00086                   notshow_jobs);
00087 
00088   bool notshow_states = false;
00089   options.AddOption('S', "notshowstates",
00090                   istring("do not print number of jobs in each state"),
00091                   notshow_states);
00092 
00093   bool show_service = false;
00094   options.AddOption('w', "showservice",
00095                   istring("print state of the service"),
00096                   show_service);
00097 
00098   std::list<std::string> params = options.Parse(argc, argv);
00099 
00100   if(show_share) { // Why?
00101     notshow_jobs=true;
00102     notshow_states=true;
00103   }
00104 
00105   if (!my_username.empty()) {
00106     struct passwd pw_;
00107     struct passwd *pw;
00108     char buf[BUFSIZ];
00109     getpwnam_r(my_username.c_str(), &pw_, buf, BUFSIZ, &pw);
00110     if(pw == NULL) {
00111       std::cout<<"Unknown user: "<<my_username<<std::endl;
00112       return 1;
00113     }
00114     my_uid=pw->pw_uid;
00115   } else {
00116     struct passwd pw_;
00117     struct passwd *pw;
00118     char buf[BUFSIZ];
00119     getpwuid_r(my_uid, &pw_, buf, BUFSIZ, &pw);
00120     if(pw == NULL) {
00121       std::cout<<"Can't recognize myself."<<std::endl;
00122       return 1;
00123     }
00124     my_username=pw->pw_name;
00125   }
00126 
00127   if (!conf_file.empty())
00128     nordugrid_config_loc(conf_file);
00129   
00130   if(!read_env_vars())
00131     exit(1);
00132   
00133   JobUsers users;
00134   
00135   if (control_dir.empty()) {
00136     JobUser my_user(my_username);
00137     std::ifstream cfile;
00138     if(!config_open(cfile)) {
00139       std::cout<<"Can't read configuration file"<<std::endl;
00140       return 1;
00141     }
00142     if (config_detect(cfile) == config_file_XML) {
00143       // take out the element that can be passed to configure_serviced_users
00144       Arc::XMLNode arex;
00145       get_arex_xml(arex);
00146       if (!arex || !configure_serviced_users(arex, users, my_uid, my_username, my_user)) {
00147         std::cout<<"Error processing configuration."<<std::endl;
00148         return 1;
00149       }
00150     } else if(!configure_serviced_users(users,my_uid,my_username,my_user)) {
00151       std::cout<<"Error processing configuration."<<std::endl;
00152       return 1;
00153     }
00154     if(users.size() == 0) {
00155       std::cout<<"No suitable users found in configuration."<<std::endl;
00156       return 1;
00157     }
00158   }
00159   else {
00160     ContinuationPlugins plugins;
00161     JobUsers::iterator jobuser = users.AddUser(my_username, NULL, control_dir);
00162     JobsList *jobs = new JobsList(*jobuser,plugins); 
00163     (*jobuser)=jobs; 
00164   }
00165 
00166   if((!notshow_jobs) || (!notshow_states) || (show_share)) {
00167     std::cout << "Looking for current jobs" << std::endl;
00168   }
00169 
00170   bool service_alive = false;
00171 
00172   unsigned int counters[JOB_STATE_NUM];
00173   unsigned int counters_pending[JOB_STATE_NUM];
00174   for(int i=0; i<JOB_STATE_NUM; i++) {
00175     counters[i] = 0;
00176     counters_pending[i] = 0;
00177   }
00178 
00179   std::map<std::string, int> share_preparing;
00180   std::map<std::string, int> share_preparing_pending;
00181   std::map<std::string, int> share_finishing;
00182   std::map<std::string, int> share_finishing_pending;
00183 
00184   unsigned int jobs_total = 0;
00185   for (JobUsers::iterator user = users.begin(); user != users.end(); ++user) {
00186     if((!notshow_jobs) || (!notshow_states) || (show_share)) {
00187     user->get_jobs()->ScanNewJobs(false);
00188     for (JobsList::iterator i=user->get_jobs()->begin(); i!=user->get_jobs()->end(); ++i) {
00189       if((!show_share) && (!notshow_jobs)) std::cout << "Job: "<<i->get_id();
00190       jobs_total++;
00191       bool pending;
00192       job_state_t new_state = job_state_read_file(i->get_id(), *user, pending);
00193       Arc::Time job_time(job_state_time(i->get_id(), *user));
00194       counters[new_state]++;
00195       if (pending) counters_pending[new_state]++;
00196       if (new_state == JOB_STATE_UNDEFINED) {
00197         std::cout<<" : ERROR : Unrecognizable state"<<std::endl;
00198         continue;
00199       }
00200       JobLocalDescription job_desc;
00201       if (!job_local_read_file(i->get_id(), *user, job_desc)) {
00202         std::cout<<" : ERROR : No local information."<<std::endl;
00203         continue;
00204       }
00205       if (show_share){
00206        if(new_state == JOB_STATE_PREPARING && !pending) share_preparing[job_desc.transfershare]++;
00207         else if(new_state == JOB_STATE_ACCEPTED && pending) share_preparing_pending[job_desc.transfershare]++;
00208         else if(new_state == JOB_STATE_FINISHING) share_finishing[job_desc.transfershare]++;
00209         else if(new_state == JOB_STATE_INLRMS && pending) {
00210           std::string jobid = i->get_id();
00211           if (job_lrms_mark_check(jobid,*user)) share_finishing_pending[job_desc.transfershare]++;
00212         };
00213       }
00214       if(!notshow_jobs) {
00215       if (!long_list) {
00216         std::cout<<" : "<<states_all[new_state].name<<" : "<<job_desc.DN<<" : "<<job_time.str()<<std::endl;
00217         continue;
00218       }
00219       std::cout<<std::endl;
00220       std::cout<<"\tState: "<<states_all[new_state].name;
00221       if (pending)
00222         std::cout<<" (PENDING)";
00223       std::cout<<std::endl;
00224       std::cout<<"\tModified: "<<job_time.str()<<std::endl;
00225       std::cout<<"\tUser: "<<job_desc.DN<<std::endl;
00226       if (!job_desc.localid.empty())
00227         std::cout<<"\tLRMS id: "<<job_desc.localid<<std::endl;
00228       if (!job_desc.jobname.empty()) 
00229         std::cout<<"\tName: "<<job_desc.jobname<<std::endl;
00230       if (!job_desc.clientname.empty()) 
00231         std::cout<<"\tFrom: "<<job_desc.clientname<<std::endl;
00232       }
00233     }
00234     }
00235     if(show_service) {
00236       if(PingFIFO(*user)) service_alive = true;
00237     }
00238   }
00239   
00240   if(show_share) {
00241     std::cout<<"\n Preparing/Pending\tTransfer share"<<std::endl;
00242     for (std::map<std::string, int>::iterator i = share_preparing.begin(); i != share_preparing.end(); i++) {
00243       std::cout<<"         "<<i->second<<"/"<<share_preparing_pending[i->first]<<"\t\t"<<i->first<<std::endl;
00244     }
00245     for (std::map<std::string, int>::iterator i = share_preparing_pending.begin(); i != share_preparing_pending.end(); i++) {
00246       if (share_preparing[i->first] == 0)
00247         std::cout<<"         0/"<<share_preparing_pending[i->first]<<"\t\t"<<i->first<<std::endl;
00248     }
00249     std::cout<<"\n Finishing/Pending\tTransfer share"<<std::endl;
00250     for (std::map<std::string, int>::iterator i = share_finishing.begin(); i != share_finishing.end(); i++) {
00251       std::cout<<"         "<<i->second<<"/"<<share_finishing_pending[i->first]<<"\t\t"<<i->first<<std::endl;
00252     }
00253     for (std::map<std::string, int>::iterator i = share_finishing_pending.begin(); i != share_finishing_pending.end(); i++) {
00254       if (share_finishing[i->first] == 0)
00255         std::cout<<"         0/"<<share_finishing_pending[i->first]<<"\t\t"<<i->first<<std::endl;
00256     }
00257     std::cout<<std::endl;
00258   }
00259   
00260   if(!notshow_states) {
00261   std::cout<<"Jobs total: "<<jobs_total<<std::endl;
00262 
00263   for (int i=0; i<JOB_STATE_UNDEFINED; i++) {
00264     std::cout<<" "<<states_all[i].name<<": "<<counters[i]<<" ("<<counters_pending[i]<<")"<<std::endl;
00265   }
00266   int max;
00267   int max_running;
00268   int max_processing;
00269   int max_processing_emergency;
00270   int max_down;
00271 
00272   JobsList::GetMaxJobs(max, max_running);
00273   JobsList::GetMaxJobsLoad(max_processing, max_processing_emergency, max_down);
00274 
00275   #undef jobs_pending
00276   #define jobs_pending 0
00277   #undef jobs_num
00278   #define jobs_num counters
00279   int accepted = JOB_NUM_ACCEPTED;
00280   int running = JOB_NUM_RUNNING;
00281   #undef jobs_num
00282   #define jobs_num counters_pending
00283   running-=JOB_NUM_RUNNING;
00284   
00285   std::cout<<" Accepted: "<<accepted<<"/"<<max<<std::endl;
00286   std::cout<<" Running: "<<running<<"/"<<max_running<<std::endl;
00287   std::cout<<" Processing: "<<
00288     counters[JOB_STATE_PREPARING]-counters_pending[JOB_STATE_PREPARING]<<"+"<<
00289     counters[JOB_STATE_FINISHING]-counters_pending[JOB_STATE_FINISHING]<<"/"<<
00290     max_processing<<"+"<<max_processing_emergency<<std::endl;
00291   }
00292   if(show_service) {
00293     std::cout<<" Service state: "<<(service_alive?"alive":"not detected")<<std::endl;
00294   }
00295   
00296   for (JobUsers::iterator user = users.begin(); user != users.end(); ++user) {
00297     JobsList* jobs = user->get_jobs();
00298     if(jobs) delete jobs;
00299   }
00300 
00301   return 0;
00302 }