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