From 12da85ef61c43476e36a05fb91410f1c91ff5232 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 10 Jun 2014 23:36:56 +0000 Subject: [PATCH] Check for execv(3) errors when reincarnating 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 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/switch.c b/src/switch.c index 6c2ef2a827..4523bd0589 100644 --- a/src/switch.c +++ b/src/switch.c @@ -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;