Belle II Software development
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
18using namespace Belle2;
19using namespace std;
20
21RFDqmServer::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
42RFDqmServer::~RFDqmServer()
43{
44 delete m_log;
45 delete m_proc;
46 delete m_conf;
47}
48
49// Functions hooked up by NSM2
50
51int 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
77int 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
119int 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
127int 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
167int 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
188void 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
209void RFDqmServer::cleanup()
210{
211 printf("RFDqmServer : cleaning up\n");
212 UnConfigure(NULL, NULL);
213 printf("RFDqmServer: Done. Exitting\n");
214 exit(-1);
215}
int Execute(char *script, int nargs, char **args)
Abstract base class for different kinds of events.
STL namespace.
Definition: nsm2.h:224