]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: respawn if rank addr changes
authorSage Weil <sage@redhat.com>
Tue, 8 Jan 2019 22:53:13 +0000 (16:53 -0600)
committerSage Weil <sage@redhat.com>
Tue, 15 Jan 2019 16:42:29 +0000 (10:42 -0600)
If the address for our rank change, then respawn!

Signed-off-by: Sage Weil <sage@redhat.com>
src/ceph_mon.cc
src/mon/Monitor.cc
src/mon/Monitor.h

index e47cf22cc8c6d87e563b66a5c9de11c037a01d68..a932a3b1b6725bf215fe2138ea598ae33f262938 100644 (file)
@@ -775,6 +775,9 @@ int main(int argc, const char **argv)
   mon = new Monitor(g_ceph_context, g_conf()->name.get_id(), store,
                    msgr, mgr_msgr, &monmap);
 
+  mon->orig_argc = argc;
+  mon->orig_argv = argv;
+
   if (force_sync) {
     derr << "flagging a forced sync ..." << dendl;
     ostringstream oss;
index eb839bcaf81b23ece397cbb44aab93daf76e11da..880b39541e0b634c1174f67c9cd7c0496f059022 100644 (file)
@@ -30,6 +30,7 @@
 #include "common/version.h"
 #include "common/blkdev.h"
 #include "common/cmdparse.h"
+#include "common/signal.h"
 
 #include "osd/OSDMap.h"
 
@@ -1021,6 +1022,54 @@ void Monitor::wait_for_paxos_write()
   }
 }
 
+void Monitor::respawn()
+{
+  dout(0) << __func__ << dendl;
+
+  char *new_argv[orig_argc+1];
+  dout(1) << " e: '" << orig_argv[0] << "'" << dendl;
+  for (int i=0; i<orig_argc; i++) {
+    new_argv[i] = (char *)orig_argv[i];
+    dout(1) << " " << i << ": '" << orig_argv[i] << "'" << dendl;
+  }
+  new_argv[orig_argc] = NULL;
+
+  /* Determine the path to our executable, test if Linux /proc/self/exe exists.
+   * This allows us to exec the same executable even if it has since been
+   * unlinked.
+   */
+  char exe_path[PATH_MAX] = "";
+#ifdef PROCPREFIX
+  if (readlink(PROCPREFIX "/proc/self/exe", exe_path, PATH_MAX-1) != -1) {
+    dout(1) << "respawning with exe " << exe_path << dendl;
+    strcpy(exe_path, PROCPREFIX "/proc/self/exe");
+  } else {
+#else
+  {
+#endif
+    /* Print CWD for the user's interest */
+    char buf[PATH_MAX];
+    char *cwd = getcwd(buf, sizeof(buf));
+    ceph_assert(cwd);
+    dout(1) << " cwd " << cwd << dendl;
+
+    /* Fall back to a best-effort: just running in our CWD */
+    strncpy(exe_path, orig_argv[0], PATH_MAX-1);
+  }
+
+  dout(1) << " exe_path " << exe_path << dendl;
+
+  unblock_all_signals(NULL);
+  execv(exe_path, new_argv);
+
+  dout(0) << "respawn execv " << orig_argv[0]
+         << " failed with " << cpp_strerror(errno) << dendl;
+
+  // We have to assert out here, because suicide() returns, and callers
+  // to respawn expect it never to return.
+  ceph_abort();
+}
+
 void Monitor::bootstrap()
 {
   dout(10) << "bootstrap" << dendl;
@@ -1045,6 +1094,14 @@ void Monitor::bootstrap()
       exit(0);
     }
   }
+  if (newrank >= 0 &&
+      monmap->get_addrs(newrank) != messenger->get_myaddrs()) {
+    dout(0) << " monmap addrs for rank " << newrank << " changed, i am "
+           << messenger->get_myaddrs()
+           << ", monmap is " << monmap->get_addrs(newrank) << ", respawning"
+           << dendl;
+    respawn();
+  }
   if (newrank != rank) {
     dout(0) << " my rank is now " << newrank << " (was " << rank << ")" << dendl;
     messenger->set_myname(entity_name_t::MON(newrank));
index a2b17f77fe6c287546204bb57adfc81c05473d0e..d0c662d74999ada7ef029331209c99a49fe7a0c2 100644 (file)
@@ -125,6 +125,9 @@ public:
 class Monitor : public Dispatcher,
                 public md_config_obs_t {
 public:
+  int orig_argc = 0;
+  const char **orig_argv = nullptr;
+
   // me
   string name;
   int rank;
@@ -593,6 +596,7 @@ private:
   void _reset();   ///< called from bootstrap, start_, or join_election
   void wait_for_paxos_write();
   void _finish_svc_election(); ///< called by {win,lose}_election
+  void respawn();
 public:
   void bootstrap();
   void join_election();