Belle II Software  release-06-02-00
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  char blank[] = "";
86  char* merger = m_conf->getconf("dqmserver", "merger");
87  char* topdir = m_conf->getconf("system", "execdir_base");
88  char* nodebase = m_conf->getconf("processor", "nodebase");
89  char* nnodes = m_conf->getconf("processor", "nnodes");
90  char* startnode = m_conf->getconf("processor", "idbase");
91  char* badlist = m_conf->getconf("processor", "badlist");
92  if (badlist == NULL)
93  badlist = blank;
94 
95  /* Should be done at STOP
96  char outfile[1024];
97  // sprintf(outfile, "dqm_e%4.4dr%6.6d.root", msg->pars[0], msg->pars[1]);
98  sprintf(outfile, "dqm_e%4.4dr%6.6d.root", m_expno, m_runno);
99  int pid_dqmmerge = m_proc->Execute(merger, outfile, nodebase, topdir, nnodes, startnode, badlist);
100  int status;
101  pid_t done = waitpid(pid_dqmmerge, &status, 0);
102  */
103 
104  // Kill DQM hrelay and hserver
105  // system("killall hrelay hserver");
106  if (m_pid_dqm != 0) {
107  int status;
108  kill(m_pid_dqm, SIGINT);
109  waitpid(m_pid_dqm, &status, 0);
110  }
111  if (m_pid_relay != 0) {
112  int status;
113  kill(m_pid_relay, SIGINT);
114  waitpid(m_pid_relay, &status, 0);
115  }
116 
117  printf("DqmServer : Unconfigure done\n");
118  return 0;
119 }
120 
121 int RFDqmServer::Start(NSMmsg* msgm, NSMcontext* msgc)
122 {
123  m_expno = msgm->pars[0];
124  m_runno = msgm->pars[1];
125  printf("DqmServer : Started. Exp = %d, Run = %d\n", m_expno, m_runno);
126  return 0;
127 }
128 
129 int RFDqmServer::Stop(NSMmsg* msg, NSMcontext*)
130 {
131  // Wait 10 sec. for basf2 completion
132  printf("DqmServer : waiting 10 sec. for basf2 completion\n");
133  sleep(10);
134 
135  // Store histogram files
136  char blank[] = "";
137  char* merger = m_conf->getconf("dqmserver", "merger");
138  char* topdir = m_conf->getconf("system", "execdir_base");
139  char* nodebase = m_conf->getconf("processor", "nodebase");
140  char* nnodes = m_conf->getconf("processor", "nnodes");
141  char* startnode = m_conf->getconf("processor", "idbase");
142  char* badlist = m_conf->getconf("processor", "badlist");
143  if (badlist == NULL)
144  badlist = blank;
145 
146  int colpid = fork();
147  if (colpid == 0) {
148  char outfile[1024];
149  // sprintf(outfile, "dqm_e%4.4dr%6.6d.root", msg->pars[0], msg->pars[1]);
150  sprintf(outfile, "dqm_e%4.4dr%6.6d.root", m_expno, m_runno);
151  // Double fork to avoid zombie
152  int dblpid = fork();
153  if (dblpid == 0) {
154  int pid_dqmmerge = m_proc->Execute(merger, outfile, nodebase, topdir, nnodes, startnode, badlist);
155  exit(0);
156  }
157  exit(0); // Exit mother of double fork
158  }
159  // Wait for the completion of mother
160  int status;
161  pid_t done = waitpid(colpid, &status, 0);
162 
163  printf("DqmServer : Stopped.\n");
164 
165  return 0;
166 }
167 
168 
169 int RFDqmServer::Restart(NSMmsg*, NSMcontext*)
170 {
171  printf("RFDqmServer : Restarted!!!!!\n");
172  /* Original Impl
173  if (m_pid_dqm != 0) {
174  kill(m_pid_dqm, SIGINT);
175  }
176  system("killall hrelay hserver");
177  fflush(stdout);
178  */
179 
180  NSMmsg* nsmmsg = NULL;
181  NSMcontext* nsmcontext = NULL;
182  RFDqmServer::UnConfigure(nsmmsg, nsmcontext);
183  sleep(2);
184  RFDqmServer::Configure(nsmmsg, nsmcontext);
185  return 0;
186 }
187 
188 // Server function
189 
190 void RFDqmServer::server()
191 {
192  while (true) {
193  pid_t pid = m_proc->CheckProcess();
194  if (pid > 0) {
195  printf("RFDqmServer : process dead. pid=%d\n", pid);
196  if (pid == m_pid_dqm)
197  m_log->Error("RFDqmServer : Hserver process dead. pid=%d\n", pid);
198  else if (pid == m_pid_relay)
199  m_log->Error("RFDqmServer : Hrelay process dead. pid=%d\n", pid);
200  }
201  int st = m_proc->CheckOutput();
202  if (st < 0) {
203  perror("RFDqmServer::server");
204  // exit ( -1 );
205  } else if (st > 0) {
206  m_log->ProcessLog(m_proc->GetFd());
207  }
208  }
209 }
210 
211 void RFDqmServer::cleanup()
212 {
213  printf("RFDqmServer : cleaning up\n");
214  UnConfigure(NULL, NULL);
215  printf("RFDqmServer: Done. Exitting\n");
216  exit(-1);
217 }
Abstract base class for different kinds of events.
Definition: nsm2.h:224