Belle II Software  release-05-01-25
RFDqmServer.cc
1 //+
2 // File : RFDqmServer.cc
3 // Description : DQM server for RFARM to accumulate histograms
4 // in a TMapFile
5 //
6 // Author : Ryosuke Itoh, IPNS, KEK
7 // Date : 4 - Sep - 2013
8 //-
9 
10 #include "daq/rfarm/manager/RFDqmServer.h"
11 
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <unistd.h>
16 
17 #include <cstring>
18 
19 using namespace Belle2;
20 using namespace std;
21 
22 RFDqmServer::RFDqmServer(string conffile)
23 {
24  // 0. Initialize configuration manager
25  m_conf = new RFConf(conffile.c_str());
26  char* nodename = m_conf->getconf("dqmserver", "nodename");
27  // char nodename[256];
28  // gethostname ( nodename, sizeof(nodename) );
29 
30  // 1. Set execution directory
31  string execdir = string(m_conf->getconf("system", "execdir_base")) + "/dqmserver";
32 
33  mkdir(execdir.c_str(), 0755);
34  chdir(execdir.c_str());
35 
36  // 2. Initialize process manager
37  m_proc = new RFProcessManager(nodename);
38 
39  // 3. Initialize LogManager
40  m_log = new RFLogManager(nodename, m_conf->getconf("system", "lognode"));
41 }
42 
43 RFDqmServer::~RFDqmServer()
44 {
45  delete m_log;
46  delete m_proc;
47  delete m_conf;
48 }
49 
50 // Functions hooked up by NSM2
51 
52 int RFDqmServer::Configure(NSMmsg*, NSMcontext*)
53 {
54  // 1. Run DqmSever
55  char* dqmserver = m_conf->getconf("dqmserver", "script");
56  char* port = m_conf->getconf("dqmserver", "port");
57  char* mapfile = m_conf->getconf("dqmserver", "mapfile");
58 
59  m_pid_dqm = m_proc->Execute(dqmserver, port, mapfile);
60 
61  // 2. Run Dqm Histogram Relay
62  char* relayhost = m_conf->getconf("dqmserver", "historelay", "host");
63  char* relayport = m_conf->getconf("dqmserver", "historelay", "port");
64  char* hrelay = m_conf->getconf("dqmserver", "historelay", "script");
65  char* interval = m_conf->getconf("dqmserver", "historelay", "interval");
66 
67  if (strcmp(relayhost, "none") != 0) {
68  printf("DqmServer : command = %s %s %s %s %s\n",
69  hrelay, mapfile, relayhost, relayport, interval);
70  m_pid_relay = m_proc->Execute(hrelay, mapfile, relayhost, relayport,
71  interval);
72  }
73 
74  return 0;
75 
76 }
77 
78 int RFDqmServer::UnConfigure(NSMmsg* nsmm, NSMcontext* nsmc)
79 {
80 
81  // Wait 10 sec. for basf2 completion
82  printf("DqmServer : waiting 10 sec. for basf2 completion\n");
83  sleep(10);
84 
85  // Store histograms in the file (make sure all event processes are stopped already)
86  char blank[] = "";
87  char* merger = m_conf->getconf("dqmserver", "merger");
88  char* topdir = m_conf->getconf("system", "execdir_base");
89  char* nodebase = m_conf->getconf("processor", "nodebase");
90  char* nnodes = m_conf->getconf("processor", "nnodes");
91  char* startnode = m_conf->getconf("processor", "idbase");
92  char* badlist = m_conf->getconf("processor", "badlist");
93  if (badlist == NULL)
94  badlist = blank;
95 
96  /* Should be done at STOP
97  char outfile[1024];
98  // sprintf(outfile, "dqm_e%4.4dr%6.6d.root", msg->pars[0], msg->pars[1]);
99  sprintf(outfile, "dqm_e%4.4dr%6.6d.root", m_expno, m_runno);
100  int pid_dqmmerge = m_proc->Execute(merger, outfile, nodebase, topdir, nnodes, startnode, badlist);
101  int status;
102  pid_t done = waitpid(pid_dqmmerge, &status, 0);
103  */
104 
105  // Kill DQM hrelay and hserver
106  // system("killall hrelay hserver");
107  if (m_pid_dqm != 0) {
108  int status;
109  kill(m_pid_dqm, SIGINT);
110  waitpid(m_pid_dqm, &status, 0);
111  }
112  if (m_pid_relay != 0) {
113  int status;
114  kill(m_pid_relay, SIGINT);
115  waitpid(m_pid_relay, &status, 0);
116  }
117 
118  printf("DqmServer : Unconfigure done\n");
119  return 0;
120 }
121 
122 int RFDqmServer::Start(NSMmsg* msgm, NSMcontext* msgc)
123 {
124  m_expno = msgm->pars[0];
125  m_runno = msgm->pars[1];
126  printf("DqmServer : Started. Exp = %d, Run = %d\n", m_expno, m_runno);
127  return 0;
128 }
129 
130 int RFDqmServer::Stop(NSMmsg* msg, NSMcontext*)
131 {
132  // Wait 10 sec. for basf2 completion
133  printf("DqmServer : waiting 10 sec. for basf2 completion\n");
134  sleep(10);
135 
136  // Store histogram files
137  char blank[] = "";
138  char* merger = m_conf->getconf("dqmserver", "merger");
139  char* topdir = m_conf->getconf("system", "execdir_base");
140  char* nodebase = m_conf->getconf("processor", "nodebase");
141  char* nnodes = m_conf->getconf("processor", "nnodes");
142  char* startnode = m_conf->getconf("processor", "idbase");
143  char* badlist = m_conf->getconf("processor", "badlist");
144  if (badlist == NULL)
145  badlist = blank;
146 
147  int colpid = fork();
148  if (colpid == 0) {
149  char outfile[1024];
150  // sprintf(outfile, "dqm_e%4.4dr%6.6d.root", msg->pars[0], msg->pars[1]);
151  sprintf(outfile, "dqm_e%4.4dr%6.6d.root", m_expno, m_runno);
152  // Double fork to avoid zombie
153  int dblpid = fork();
154  if (dblpid == 0) {
155  int pid_dqmmerge = m_proc->Execute(merger, outfile, nodebase, topdir, nnodes, startnode, badlist);
156  exit(0);
157  }
158  exit(0); // Exit mother of double fork
159  }
160  // Wait for the completion of mother
161  int status;
162  pid_t done = waitpid(colpid, &status, 0);
163 
164  printf("DqmServer : Stopped.\n");
165 
166  return 0;
167 }
168 
169 
170 int RFDqmServer::Restart(NSMmsg*, NSMcontext*)
171 {
172  printf("RFDqmServer : Restarted!!!!!\n");
173  /* Original Impl
174  if (m_pid_dqm != 0) {
175  kill(m_pid_dqm, SIGINT);
176  }
177  system("killall hrelay hserver");
178  fflush(stdout);
179  */
180 
181  NSMmsg* nsmmsg = NULL;
182  NSMcontext* nsmcontext = NULL;
183  RFDqmServer::UnConfigure(nsmmsg, nsmcontext);
184  sleep(2);
185  RFDqmServer::Configure(nsmmsg, nsmcontext);
186  return 0;
187 }
188 
189 // Server function
190 
191 void RFDqmServer::server()
192 {
193  while (true) {
194  pid_t pid = m_proc->CheckProcess();
195  if (pid > 0) {
196  printf("RFDqmServer : process dead. pid=%d\n", pid);
197  if (pid == m_pid_dqm)
198  m_log->Error("RFDqmServer : Hserver process dead. pid=%d\n", pid);
199  else if (pid == m_pid_relay)
200  m_log->Error("RFDqmServer : Hrelay process dead. pid=%d\n", pid);
201  }
202  int st = m_proc->CheckOutput();
203  if (st < 0) {
204  perror("RFDqmServer::server");
205  // exit ( -1 );
206  } else if (st > 0) {
207  m_log->ProcessLog(m_proc->GetFd());
208  }
209  }
210 }
211 
212 void RFDqmServer::cleanup()
213 {
214  printf("RFDqmServer : cleaning up\n");
215  UnConfigure(NULL, NULL);
216  printf("RFDqmServer: Done. Exitting\n");
217  exit(-1);
218 }
NSMmsg
Definition: nsm2.h:217
Belle2::RFLogManager
Definition: RFLogManager.h:18
Belle2::RFProcessManager
Definition: RFProcessManager.h:22
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::RFConf
Definition: RFConf.h:24
NSMcontext_struct
Definition: nsmlib2.h:66