summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2004-07-23 20:40:46 (UTC)
committer Michael Krelin <hacker@klever.net>2004-07-23 20:40:46 (UTC)
commit546858a1e4d13d179a6af27b474e1396cfdf0c29 (patch) (unidiff)
treeac19b0ff5e4b3164ad5375bda112a9d6d2f88c2b
parent76921288a0aa39acb53102863523c388b5d0f9ee (diff)
downloaddudki-546858a1e4d13d179a6af27b474e1396cfdf0c29.zip
dudki-546858a1e4d13d179a6af27b474e1396cfdf0c29.tar.gz
dudki-546858a1e4d13d179a6af27b474e1396cfdf0c29.tar.bz2
the ability to check/kill/reload any of the processes being monitored added.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--man/dudki.8.in11
-rw-r--r--src/dudki.cc61
-rw-r--r--src/process.cc30
-rw-r--r--src/process.h2
4 files changed, 65 insertions, 39 deletions
diff --git a/man/dudki.8.in b/man/dudki.8.in
index 3011034..05db733 100644
--- a/man/dudki.8.in
+++ b/man/dudki.8.in
@@ -26,6 +26,7 @@ dudki \- a process monitoring daemon
26.if \*[longopt] [\fB--ensure\fR] 26.if \*[longopt] [\fB--ensure\fR]
27[\fB-t\fR] 27[\fB-t\fR]
28.if \*[longopt] [\fB--test\fR] 28.if \*[longopt] [\fB--test\fR]
29[\fI<process-list>\fR]
29 30
30.SH DESCRIPTION 31.SH DESCRIPTION
31 32
@@ -45,15 +46,19 @@ Specify the configuration file to use (default is
45.TP 46.TP
46.ie \*[longopt] \fB-k\fR, \fB--kill\fR 47.ie \*[longopt] \fB-k\fR, \fB--kill\fR
47.el \fB-k\fR 48.el \fB-k\fR
48Stop the running instance by sending the \fBSIGTERM\fR signal. 49Stop the running instance by sending the \fBSIGTERM\fR signal. If no process
50name specified on the command line, dudki kills his own running instance.
49.TP 51.TP
50.ie \*[longopt] \fB-r\fR, \fB--reload\fR 52.ie \*[longopt] \fB-r\fR, \fB--reload\fR
51.el \fB-r\fR 53.el \fB-r\fR
52Reload the running instance by sending the \fBSIGHUP\fR signal. 54Reload the running instance by sending the \fBSIGHUP\fR signal. Like with
55\fB-k\fR, if no process name specified on the command line, dudki sends
56\fBSIGHUP\fR to his own running instance.
53.TP 57.TP
54.ie \*[longopt] \fB-c\fR, \fB--check\fR 58.ie \*[longopt] \fB-c\fR, \fB--check\fR
55.el \fB-c\fR 59.el \fB-c\fR
56Check if dudki is running. Exit with non-zero status if not. 60Check if dudki is running. Exit with non-zero status if not. The same target
61rules as in \fB-k\fR and \fB-r\fR apply here.
57.TP 62.TP
58.ie \*[longopt] \fB-e\fR, \fB--ensure\fR 63.ie \*[longopt] \fB-e\fR, \fB--ensure\fR
59.el \fB-e\fR 64.el \fB-e\fR
diff --git a/src/dudki.cc b/src/dudki.cc
index b4e95a7..e91ad5e 100644
--- a/src/dudki.cc
+++ b/src/dudki.cc
@@ -62,12 +62,11 @@ int main(int argc,char **argv) {
62 enum { 62 enum {
63 op_default, 63 op_default,
64 op_work, 64 op_work,
65 op_hup, 65 op_signal,
66 op_term,
67 op_check,
68 op_ensure, 66 op_ensure,
69 op_test 67 op_test
70 } op = op_default; 68 } op = op_default;
69 int op_signum = 0;
71 while(true) { 70 while(true) {
72 #defineSHORTOPTSTRING "f:hVLrkcet" 71 #defineSHORTOPTSTRING "f:hVLrkcet"
73#ifdef HAVE_GETOPT_LONG 72#ifdef HAVE_GETOPT_LONG
@@ -93,7 +92,8 @@ int main(int argc,char **argv) {
93 switch(c) { 92 switch(c) {
94 case 'h': 93 case 'h':
95 cerr << PHEADER << endl 94 cerr << PHEADER << endl
96 << PCOPY << endl << endl << 95 << PCOPY << endl << endl
96 << " " << argv[0] << " [options] [processes]" << endl << endl <<
97#ifdef HAVE_GETOPT_LONG 97#ifdef HAVE_GETOPT_LONG
98 " -h, --help\n" 98 " -h, --help\n"
99 " --usage display this text\n" 99 " --usage display this text\n"
@@ -102,9 +102,11 @@ int main(int argc,char **argv) {
102 " -f filename, --config=filename\n" 102 " -f filename, --config=filename\n"
103 " specify the configuration file to use\n" 103 " specify the configuration file to use\n"
104 "\n" 104 "\n"
105 " -k, --kill stop running instance\n" 105 " -k, --kill stop running instance (send SIGTERM)\n"
106 " -r, --reload reload running instance (send SIGHUP)\n" 106 " -r, --reload reload running instance (send SIGHUP)\n"
107 " -c, --check check if dudki is running\n" 107 " -c, --check check if the process is running\n"
108 " (the above commands operate on dudki itself if no\n"
109 " process name has been specified)\n"
108 " -e, --ensure ensure that dudki is running\n" 110 " -e, --ensure ensure that dudki is running\n"
109 " -t, --test test configuration file and exit" 111 " -t, --test test configuration file and exit"
110#else /* !HAVE_GETOPT_LONG */ 112#else /* !HAVE_GETOPT_LONG */
@@ -113,9 +115,11 @@ int main(int argc,char **argv) {
113 " -L show license\n" 115 " -L show license\n"
114 " -f filename specify the configuration file to use\n" 116 " -f filename specify the configuration file to use\n"
115 "\n" 117 "\n"
116 " -k stop running instance\n" 118 " -k stop running instance (send SIGTERM)\n"
117 " -r reload running instance (send SIGHUP)\n" 119 " -r reload running instance (send SIGHUP)\n"
118 " -c check if dudki is running\n" 120 " -c check if the process is running\n"
121 " (the above commands operate on dudki itself if no\n"
122 " process name has been specified)\n"
119 " -e ensure that dudki is running\n" 123 " -e ensure that dudki is running\n"
120 " -t test configuration file and exit" 124 " -t test configuration file and exit"
121#endif /* /HAVE_GETOPT_LONG */ 125#endif /* /HAVE_GETOPT_LONG */
@@ -139,21 +143,21 @@ int main(int argc,char **argv) {
139 cerr << "Can't obey two or more orders at once" << endl; 143 cerr << "Can't obey two or more orders at once" << endl;
140 exit(1); 144 exit(1);
141 } 145 }
142 op = op_term; 146 op = op_signal; op_signum = SIGTERM;
143 break; 147 break;
144 case 'r': 148 case 'r':
145 if(op!=op_default) { 149 if(op!=op_default) {
146 cerr << "Can't obey two or more orders at once" << endl; 150 cerr << "Can't obey two or more orders at once" << endl;
147 exit(1); 151 exit(1);
148 } 152 }
149 op = op_hup; 153 op = op_signal; op_signum = SIGHUP;
150 break; 154 break;
151 case 'c': 155 case 'c':
152 if(op!=op_default) { 156 if(op!=op_default) {
153 cerr << "Can't obey two or more orders at once" << endl; 157 cerr << "Can't obey two or more orders at once" << endl;
154 exit(1); 158 exit(1);
155 } 159 }
156 op = op_check; 160 op = op_signal; op_signum = 0;
157 break; 161 break;
158 case 'e': 162 case 'e':
159 if(op!=op_default) { 163 if(op!=op_default) {
@@ -187,18 +191,31 @@ int main(int argc,char **argv) {
187 case op_test: 191 case op_test:
188 cerr << "Configuration OK" << endl; 192 cerr << "Configuration OK" << endl;
189 break; 193 break;
190 case op_hup: 194 case op_signal:
191 signal_self(config,SIGHUP); 195 try {
192 break; 196 if(optind>=argc) {
193 case op_term: 197 signal_self(config,op_signum);
194 signal_self(config,SIGTERM); 198 }else{
195 break; 199 int failures = 0;
196 case op_check: 200 for(int narg=optind;narg<argc;narg++) {
197 try{ 201 try {
198 signal_self(config,0); 202 processes_t::const_iterator i = config.processes.find(argv[narg]);
199 exit(0); 203 if(i==config.processes.end())
204 throw runtime_error("no such process configured");
205 i->second.signal(op_signum);
206 }catch(exception& e) {
207 cerr << "dudki(" << argv[narg] << "): " << e.what() << endl;
208 failures++;
209 }
210 }
211 if(failures)
212 throw runtime_error("not all processes have been successfully signaled");
213 }
214 if(!op_signum)
215 exit(0);
200 }catch(exception& e) { 216 }catch(exception& e) {
201 exit(1); 217 if(!op_signum)
218 exit(1);
202 } 219 }
203 case op_ensure: 220 case op_ensure:
204 try { 221 try {
diff --git a/src/process.cc b/src/process.cc
index bfab311..1ffac9f 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -15,21 +15,10 @@ using namespace std;
15#include "configuration.h" 15#include "configuration.h"
16 16
17void process::check(const string& id,configuration& config) { 17void process::check(const string& id,configuration& config) {
18 bool running = false; 18 try {
19 ifstream pids(pidfile.c_str(),ios::in); 19 signal(0);
20 if(pids) {
21 pid_t pid = 0;
22 pids >> pid;
23 pids.close();
24 if(pid) {
25 if(!kill(pid,0)) {
26 running = true;
27 }
28 }
29 }
30 if(running){
31 patience = 0; 20 patience = 0;
32 }else{ 21 }catch(exception& e) {
33 if(patience>60) { // TODO: configurable 22 if(patience>60) { // TODO: configurable
34 patience = 0; 23 patience = 0;
35 }else{ 24 }else{
@@ -185,3 +174,16 @@ void process::notify_mailto(const string& email,const string& id,const string& e
185 waitpid(pid,&status,0); 174 waitpid(pid,&status,0);
186 // TODO: check the return code 175 // TODO: check the return code
187} 176}
177
178void process::signal(int signum) const {
179 ifstream pids(pidfile.c_str(),ios::in);
180 if(!pids)
181 throw runtime_error("no pidfile found");
182 pid_t pid = 0;
183 pids >> pid;
184 pids.close();
185 if(!pid)
186 throw runtime_error("no pid in pidfile");
187 if(kill(pid,signum))
188 throw runtime_error("failed to signal process");
189}
diff --git a/src/process.h b/src/process.h
index b6d7091..27ee049 100644
--- a/src/process.h
+++ b/src/process.h
@@ -29,6 +29,8 @@ class process {
29 void do_notify(const string& id,const string& event,const string& description,configuration& config); 29 void do_notify(const string& id,const string& event,const string& description,configuration& config);
30 void notify_mailto(const string& email,const string& id,const string& event, 30 void notify_mailto(const string& email,const string& id,const string& event,
31 const string& description,configuration& config); 31 const string& description,configuration& config);
32
33 void signal(int signum) const;
32}; 34};
33 35
34typedef map<string,process> processes_t; 36typedef map<string,process> processes_t;