Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mgr/MgrStandby: respawn when deactivated #15557

Merged
merged 1 commit into from Jun 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ceph_mgr.cc
Expand Up @@ -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;
Expand Down
55 changes: 46 additions & 9 deletions src/mgr/MgrStandby.cc
Expand Up @@ -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"
Expand All @@ -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")),
Expand All @@ -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)
{
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/mgr/MgrStandby.h
Expand Up @@ -55,14 +55,17 @@ class MgrStandby : public Dispatcher,

std::shared_ptr<Mgr> active_mgr;

int orig_argc;
const char **orig_argv;

std::string state_str();

void handle_mgr_map(MMgrMap *m);
void _update_log_config();
void send_beacon();

public:
MgrStandby();
MgrStandby(int argc, const char **argv);
~MgrStandby() override;

bool ms_dispatch(Message *m) override;
Expand All @@ -74,6 +77,7 @@ class MgrStandby : public Dispatcher,

int init();
void shutdown();
void respawn();
int main(vector<const char *> args);
void handle_signal(int signum);
void tick();
Expand Down