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();
+    }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.