Re: HTTP admin restart issues
Alexander Malysh <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Jakob, sorry for delay. Please try attached patch that should fix pid file issue by restart and issue with smsbox/wapbox shutdown when bearerbox has crashed. Let me know how it works for you and I will commit this fix. Thanks, Alexander Malysh Am 31.08.2011 um 10:38 schrieb Jacob Eiler: > Hi. > > Thank you for the feedback. > > On Tue, 2011-08-30 at 23:00 +0300, Nikos Balkanas wrote: > >> 3. If bearerbox is in parachute mode and restarted for any reason, >> smsbox goes down and stays down. This is caused by failed heartbeats. >> It can be fixed by introducing a small delay witth retry in smsbox, if >> it realizes that bearerbox connectiuon is dropped. > > Actually the cause is the closing of the bearerbox-connection, causing > read_from_bearerbox_real to return -1 and in turn the smsbox to > shutdown. > > >> (1) Could you please post panic logs?I don't think it is due to the >> pid file. In my experience web restart fails always, because it >> doesn't preserve the original location and execvp() can't find the >> executable. Solution is to save original launch directory (i.e. >> "/usr/local/bin") and then do a chdir() just before you call execvp. >> You see, after initialization, bearerbox runs from "/" and all >> relative paths are broken. This could include the pid file as well. > > This is only the case when combined with --daemonize/-d. At any rate I > start Kannel absolute paths for all parameters (executable, pid-file, > configuration-file. > > Here is the panic logs: > > ... > 2011-08-31 10:31:47 [3755] [0] DEBUG: MO concatenated message handling > cleaned up > 2011-08-31 10:31:47 [3755] [0] INFO: Total WDP messages: received 0, > sent 0 > 2011-08-31 10:31:47 [3755] [0] INFO: Total SMS messages: received 0, dlr > 0, sent 0, dlr 0 > 2011-08-31 10:31:47 [3755] [0] DEBUG: Immutable octet strings: 257. > 2011-08-31 10:31:47 [3755] [0] PANIC: Could not open pid-file > `/tmp/core.pid' > 2011-08-31 10:31:47 [3755] [0] PANIC: System error 17: File exists > 2011-08-31 10:31:47 [3755] [0] PANIC: ./gw/bearerbox(gw_panic+0xbd) > [0x80f1dcd] > 2011-08-31 10:31:47 [3755] [0] PANIC: ./gw/bearerbox(get_and_set_debugs > +0xaeb) [0x80fe9cb] > 2011-08-31 10:31:47 [3755] [0] PANIC: ./gw/bearerbox(main+0x87) > [0x80530a7] > 2011-08-31 10:31:47 [3755] [0] > PANIC: /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7) > [0xb737be37] > 2011-08-31 10:31:47 [3755] [0] PANIC: ./gw/bearerbox() [0x8052a41] > > > >> (2). Same solution as in (3). Introduce a small delay to smsbox. >> However, for this you don't need to modify the sources, you can just >> delay it in the init script. > > Yes, provided I just the parachute option and an init-script. > > In my opinion it make little sense to provide a 'restart' command, when > in fact only the bearerbox is restarted and all other boxes simply shut > down. > > /Jacob > > > -- > Jacob Eiler > Apide ApS > e: [email protected] > t: +45 2374 0486 > w: apide.com > > >
restart_fix.patch
(application/octet-stream, 5.5 KB)
diff --git a/gw/bearerbox.c b/gw/bearerbox.c
index 4325cdf..ffb04b3 100644
--- a/gw/bearerbox.c
+++ b/gw/bearerbox.c
@@ -791,10 +791,12 @@ int main(int argc, char **argv)
cfg_destroy(cfg);
octstr_destroy(cfg_filename);
dlr_shutdown();
- gwlib_shutdown();
- if (restart == 1)
- execvp(argv[0],argv);
+ /* now really restart */
+ if (restart)
+ restart_box(argv);
+
+ gwlib_shutdown();
return 0;
}
diff --git a/gw/shared.c b/gw/shared.c
index 42dd607..b7bb9df 100644
--- a/gw/shared.c
+++ b/gw/shared.c
@@ -60,6 +60,7 @@
* Lars Wirzenius
*/
+#include <errno.h>
#include <libxml/xmlversion.h>
#include "gwlib/gwlib.h"
@@ -274,3 +275,21 @@ error:
return NULL;
}
+int restart_box(char **argv)
+{
+ int rc;
+
+ if (!(rc = fork())) {
+ /*
+ * Sleep a while in order to get father
+ * process time to cleanup things
+ */
+ gwthread_sleep(1.0);
+ if (execvp(argv[0],argv) == -1)
+ error(errno, "Unable to start new process.");
+ } else if (rc == -1)
+ error(errno, "Could not restart, exiting...");
+
+ return rc == -1 ? -1 : 0;
+}
+
diff --git a/gw/shared.h b/gw/shared.h
index 855b32c..8665aaf 100644
--- a/gw/shared.h
+++ b/gw/shared.h
@@ -130,6 +130,11 @@ int deliver_to_bearerbox(Msg *msg);
Octstr *parse_date(Octstr *date);
+/*
+ * Restarts process with a given params
+ */
+int restart_box(char **argv);
+
#endif
diff --git a/gw/smsbox.c b/gw/smsbox.c
index 2968061..e7f11db 100644
--- a/gw/smsbox.c
+++ b/gw/smsbox.c
@@ -242,9 +242,12 @@ static void read_messages_from_bearerbox(void)
while (program_status != shutting_down) {
/* block infinite for reading messages */
ret = read_from_bearerbox(&msg, INFINITE_TIME);
- if (ret == -1)
+ if (ret == -1) {
+ error(0, "Bearerbox is gone, restarting");
+ program_status = shutting_down;
+ restart = 1;
break;
- else if (ret == 1) /* timeout */
+ } else if (ret == 1) /* timeout */
continue;
else if (msg == NULL) /* just to be sure, may not happens */
break;
@@ -3618,15 +3621,13 @@ int main(int argc, char **argv)
* Otherwise we will fail while trying to connect to bearerbox!
*/
if (restart) {
- gwthread_sleep(5.0);
+ gwthread_sleep(10.0);
+ /* now really restart */
+ restart_box(argv);
}
gwlib_shutdown();
- /* now really restart */
- if (restart)
- execvp(argv[0], argv);
-
return 0;
}
diff --git a/gw/wapbox.c b/gw/wapbox.c
index 9688886..988bf43 100644
--- a/gw/wapbox.c
+++ b/gw/wapbox.c
@@ -775,9 +775,12 @@ int main(int argc, char **argv)
/* block infinite for reading messages */
ret = read_from_bearerbox(&msg, INFINITE_TIME);
- if (ret == -1)
+ if (ret == -1) {
+ error(0, "Bearerbox is gone, restarting");
+ program_status = shutting_down;
+ restart = 1;
break;
- else if (ret == 1) /* timeout */
+ } else if (ret == 1) /* timeout */
continue;
else if (msg == NULL) /* just to be sure, may not happens */
break;
@@ -861,15 +864,13 @@ int main(int argc, char **argv)
* Otherwise we will fail while trying to connect to bearerbox!
*/
if (restart) {
- gwthread_sleep(5.0);
+ gwthread_sleep(10.0);
+ /* now really restart */
+ restart_box(argv);
}
gwlib_shutdown();
- /* now really restart */
- if (restart)
- execvp(argv[0], argv);
-
return 0;
}
diff --git a/gwlib/gwlib.c b/gwlib/gwlib.c
index c74c009..b3e8448 100644
--- a/gwlib/gwlib.c
+++ b/gwlib/gwlib.c
@@ -107,3 +107,9 @@ void gwlib_shutdown(void)
gwmem_shutdown();
init = 0;
}
+
+int gwlib_initialized(void)
+{
+ return init;
+}
+
diff --git a/gwlib/gwlib.h b/gwlib/gwlib.h
index 7830371..3f4f2e5 100644
--- a/gwlib/gwlib.h
+++ b/gwlib/gwlib.h
@@ -107,6 +107,7 @@
void gwlib_assert_init(void);
void gwlib_init(void);
void gwlib_shutdown(void);
+int gwlib_initialized(void);
#ifdef NO_GWASSERT
#define gwlib_assert_init() ((void) 0)
diff --git a/gwlib/utils.c b/gwlib/utils.c
index 35fc8c3..c5a774a 100644
--- a/gwlib/utils.c
+++ b/gwlib/utils.c
@@ -103,6 +103,8 @@
/* pid of child process when parachute is used */
static pid_t child_pid = -1;
+/* pid of pid file owner */
+static pid_t pidfile_owner_pid = -1;
/* saved child signal handlers */
static struct sigaction child_actions[32];
/* just a flag that child signal handlers are stored */
@@ -350,7 +352,7 @@ static void write_pid_file(void)
if (!file)
panic(errno, "Could not open file-stream `%s'", pid_file);
- fprintf(file, "%ld\n", (long) getpid());
+ fprintf(file, "%ld\n", (long) (pidfile_owner_pid = getpid()));
fclose(file);
}
@@ -359,12 +361,21 @@ static void remove_pid_file(void)
if (!pid_file)
return;
- /* ensure we don't called from child process */
- if (child_pid == 0)
+ /* ensure that only pidfile owner can remove it */
+ if (pidfile_owner_pid != getpid())
return;
- if (-1 == unlink(pid_file))
+ if (-1 == unlink(pid_file)) {
+ int initdone = gwlib_initialized();
+ /* we are called at exit so gwlib may be shutdown already, init again */
+ if (!initdone) {
+ gwlib_init();
+ log_set_syslog("kannel", 0);
+ }
error(errno, "Could not unlink pid-file `%s'", pid_file);
+ if (!initdone)
+ gwlib_shutdown();
+ }
}