]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/MgrStandby: respawn when deactivated 15557/head
authorSage Weil <sage@redhat.com>
Wed, 7 Jun 2017 20:54:19 +0000 (16:54 -0400)
committerSage Weil <sage@redhat.com>
Wed, 7 Jun 2017 20:54:19 +0000 (16:54 -0400)
- It is ugly to unwind all of the Mgr state so that we can reactivate
  later.
- It is perhaps impossible to do shut down the python state reliably.
- Respawning provides a clean state and is reliable.

This mostly just copies MDSServer::respawn().

Fixes: http://tracker.ceph.com/issues/19595
Fixes: http://tracker.ceph.com/issues/19549
Signed-off-by: Sage Weil <sage@redhat.com>
src/ceph_mgr.cc
src/mgr/MgrStandby.cc
src/mgr/MgrStandby.h

index ae5feb3751acd15039bd9c711020275a8c725021..051bed7094647f808f1a9a3a20e8724d5f1fdd3f 100644 (file)
@@ -56,7 +56,7 @@ int main(int argc, const char **argv)
   global_init_chdir(g_ceph_context);
   common_init_finish(g_ceph_context);
 
-  MgrStandby mgr;
+  MgrStandby mgr(argc, argv);
   int rc = mgr.init();
   if (rc != 0) {
       std::cerr << "Error in initialization: " << cpp_strerror(rc) << std::endl;
index 3d68cfe7f7e01540a405ae59def48260de4cb394..12a211b120b1588bfb5662c1ce47210150e1d6c0 100644 (file)
@@ -14,6 +14,8 @@
 #include <Python.h>
 
 #include "common/errno.h"
+#include "common/signal.h"
+#include "include/compat.h"
 
 #include "include/stringify.h"
 #include "global/global_context.h"
@@ -33,7 +35,7 @@
 #define dout_prefix *_dout << "mgr " << __func__ << " "
 
 
-MgrStandby::MgrStandby() :
+MgrStandby::MgrStandby(int argc, const char **argv) :
   Dispatcher(g_ceph_context),
   monc{g_ceph_context},
   client_messenger(Messenger::create_client_messenger(g_ceph_context, "mgr")),
@@ -44,7 +46,9 @@ MgrStandby::MgrStandby() :
   audit_clog(log_client.create_channel(CLOG_CHANNEL_AUDIT)),
   lock("MgrStandby::lock"),
   timer(g_ceph_context, lock),
-  active_mgr(nullptr)
+  active_mgr(nullptr),
+  orig_argc(argc),
+  orig_argv(argv)
 {
 }
 
@@ -202,6 +206,45 @@ void MgrStandby::shutdown()
   client_messenger->shutdown();
 }
 
+void MgrStandby::respawn()
+{
+  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] = "";
+  if (readlink(PROCPREFIX "/proc/self/exe", exe_path, PATH_MAX-1) == -1) {
+    /* Print CWD for the user's interest */
+    char buf[PATH_MAX];
+    char *cwd = getcwd(buf, sizeof(buf));
+    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);
+  } else {
+    dout(1) << "respawning with exe " << exe_path << dendl;
+    strcpy(exe_path, PROCPREFIX "/proc/self/exe");
+  }
+
+  dout(1) << " exe_path " << exe_path << dendl;
+
+  unblock_all_signals(NULL);
+  execv(exe_path, new_argv);
+
+  derr << "respawn execv " << orig_argv[0]
+       << " failed with " << cpp_strerror(errno) << dendl;
+  ceph_abort();
+}
+
 void MgrStandby::_update_log_config()
 {
   map<string,string> log_to_monitors;
@@ -249,13 +292,7 @@ void MgrStandby::handle_mgr_map(MMgrMap* mmap)
   } else {
     if (active_mgr != nullptr) {
       derr << "I was active but no longer am" << dendl;
-      active_mgr->shutdown();
-      active_mgr.reset();
-
-      // FIXME: reset monc connection so that our old subscriptions go away
-      // and we stop getting MLog and MMgrDigest messages.  (We do something
-      // similar in Mgr::init().)
-      monc.reopen_session();
+      respawn();
     }
   }
 
index 8c1c144e73ff45c94dac302b6f395f941f32b145..79cdaa0c00dbc10e7d47cb0b7c8b337eba4db3b4 100644 (file)
@@ -55,6 +55,9 @@ protected:
 
   std::shared_ptr<Mgr> active_mgr;
 
+  int orig_argc;
+  const char **orig_argv;
+
   std::string state_str();
 
   void handle_mgr_map(MMgrMap *m);
@@ -62,7 +65,7 @@ protected:
   void send_beacon();
 
 public:
-  MgrStandby();
+  MgrStandby(int argc, const char **argv);
   ~MgrStandby() override;
 
   bool ms_dispatch(Message *m) override;
@@ -74,6 +77,7 @@ public:
 
   int init();
   void shutdown();
+  void respawn();
   int main(vector<const char *> args);
   void handle_signal(int signum);
   void tick();