]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Check for execv(3) errors when reincarnating
authorTravis Cross <tc@traviscross.com>
Tue, 10 Jun 2014 23:36:56 +0000 (23:36 +0000)
committerTravis Cross <tc@traviscross.com>
Tue, 10 Jun 2014 23:52:36 +0000 (23:52 +0000)
When -reincarnate-reexec is given we run execv to restart FS.  If
argv[0] isn't a full pathname then execv is going to fail.  While not
common for a FS system started by init, this is a common occurrence
when FS is started from the shell.

Now if execv fails, we'll try execvp.  If that fails too then we'll
fall back on the normal reincarnation behavior.

Previously what would happen in that case is god would descend from
the heavens and become mortal.  Leaving heaven absent, all hope for
reincarnation was lost.

(That is, we'd simply return from reincarnate_protect and the
supervisor process would become the new instance of FS, so the trick
would only work once.)

src/switch.c

index 6c2ef2a8270fb8e5cbcf8a80cd063d29a06eed5c..4523bd0589225724723b9302ccc839ff8b42da4a 100644 (file)
@@ -399,7 +399,19 @@ static void reincarnate_protect(char **argv) {
                        sigaction(SIGTERM, &sa15_prev, NULL);
                        sigaction(SIGCHLD, &sa17_prev, NULL);
                        if (argv) {
-                               execv(argv[0], argv); return;
+                               if (execv(argv[0], argv) == -1) {
+                                       char buf[256];
+                                       fprintf(stderr, "Reincarnate execv() failed: %d %s\n", errno,
+                                                       strerror_r(errno, buf, sizeof(buf)));
+                               }
+                               fprintf(stderr, "Trying reincarnate-reexec plan B...\n");
+                               if (execvp(argv[0], argv) == -1) {
+                                       char buf[256];
+                                       fprintf(stderr, "Reincarnate execvp() failed: %d %s\n", errno,
+                                                       strerror_r(errno, buf, sizeof(buf)));
+                               }
+                               fprintf(stderr, "Falling back to normal reincarnate behavior...\n");
+                               goto refork;
                        } else goto refork;
                }
                goto rewait;