From 111b7b26a868e5a631e7f93720617801306a1ece Mon Sep 17 00:00:00 2001 From: Brad Hubbard Date: Fri, 16 Jun 2017 13:28:23 +1000 Subject: [PATCH] mon: Log errors at startup Currently we send error messages to stderr but these tend to be swallowed up by the init scripts. Send error messages to derr instead so they go to both stderr and the cluster log. Fixes: http://tracker.ceph.com/issues/14088 Signed-off-by: Brad Hubbard --- src/ceph_mon.cc | 111 ++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/src/ceph_mon.cc b/src/ceph_mon.cc index a7be9694a922a..0b5d4edfd7934 100644 --- a/src/ceph_mon.cc +++ b/src/ceph_mon.cc @@ -108,7 +108,7 @@ int check_mon_data_exists() struct stat buf; if (::stat(mon_data.c_str(), &buf)) { if (errno != ENOENT) { - cerr << "stat(" << mon_data << ") " << cpp_strerror(errno) << std::endl; + derr << "stat(" << mon_data << ") " << cpp_strerror(errno) << dendl; } return -errno; } @@ -132,7 +132,7 @@ int check_mon_data_empty() DIR *dir = ::opendir(mon_data.c_str()); if (!dir) { - cerr << "opendir(" << mon_data << ") " << cpp_strerror(errno) << std::endl; + derr << "opendir(" << mon_data << ") " << cpp_strerror(errno) << dendl; return -errno; } int code = 0; @@ -147,7 +147,7 @@ int check_mon_data_empty() } } if (!de && errno) { - cerr << "readdir(" << mon_data << ") " << cpp_strerror(errno) << std::endl; + derr << "readdir(" << mon_data << ") " << cpp_strerror(errno) << dendl; code = -errno; } @@ -273,23 +273,23 @@ int main(int argc, const char **argv) } } if (!args.empty()) { - cerr << "too many arguments: " << args << std::endl; + derr << "too many arguments: " << args << dendl; usage(); } if (force_sync && !yes_really) { - cerr << "are you SURE you want to force a sync? this will erase local data and may\n" - << "break your mon cluster. pass --yes-i-really-mean-it if you do." << std::endl; + derr << "are you SURE you want to force a sync? this will erase local data and may\n" + << "break your mon cluster. pass --yes-i-really-mean-it if you do." << dendl; exit(1); } if (g_conf->mon_data.empty()) { - cerr << "must specify '--mon-data=foo' data path" << std::endl; + derr << "must specify '--mon-data=foo' data path" << dendl; usage(); } if (g_conf->name.get_id().empty()) { - cerr << "must specify id (--id or --name mon.)" << std::endl; + derr << "must specify id (--id or --name mon.)" << dendl; usage(); } @@ -299,25 +299,25 @@ int main(int argc, const char **argv) int err = check_mon_data_exists(); if (err == -ENOENT) { if (::mkdir(g_conf->mon_data.c_str(), 0755)) { - cerr << "mkdir(" << g_conf->mon_data << ") : " - << cpp_strerror(errno) << std::endl; + derr << "mkdir(" << g_conf->mon_data << ") : " + << cpp_strerror(errno) << dendl; exit(1); } } else if (err < 0) { - cerr << "error opening '" << g_conf->mon_data << "': " - << cpp_strerror(-err) << std::endl; + derr << "error opening '" << g_conf->mon_data << "': " + << cpp_strerror(-err) << dendl; exit(-err); } err = check_mon_data_empty(); if (err == -ENOTEMPTY) { // Mon may exist. Let the user know and exit gracefully. - cerr << "'" << g_conf->mon_data << "' already exists and is not empty" - << ": monitor may already exist" << std::endl; + derr << "'" << g_conf->mon_data << "' already exists and is not empty" + << ": monitor may already exist" << dendl; exit(0); } else if (err < 0) { - cerr << "error checking if '" << g_conf->mon_data << "' is empty: " - << cpp_strerror(-err) << std::endl; + derr << "error checking if '" << g_conf->mon_data << "' is empty: " + << cpp_strerror(-err) << dendl; exit(-err); } @@ -334,7 +334,7 @@ int main(int argc, const char **argv) if (g_conf->monmap.length()) { int err = monmapbl.read_file(g_conf->monmap.c_str(), &error); if (err < 0) { - cerr << argv[0] << ": error reading " << g_conf->monmap << ": " << error << std::endl; + derr << argv[0] << ": error reading " << g_conf->monmap << ": " << error << dendl; exit(1); } try { @@ -344,13 +344,16 @@ int main(int argc, const char **argv) monmap.set_epoch(0); } catch (const buffer::error& e) { - cerr << argv[0] << ": error decoding monmap " << g_conf->monmap << ": " << e.what() << std::endl; + derr << argv[0] << ": error decoding monmap " << g_conf->monmap << ": " << e.what() << dendl; exit(1); } } else { - int err = monmap.build_initial(g_ceph_context, cerr); + ostringstream oss; + int err = monmap.build_initial(g_ceph_context, oss); + if (oss.tellp()) + derr << oss.str() << dendl; if (err < 0) { - cerr << argv[0] << ": warning: no initial monitors; must use admin socket to feed hints" << std::endl; + derr << argv[0] << ": warning: no initial monitors; must use admin socket to feed hints" << dendl; } // am i part of the initial quorum? @@ -396,7 +399,7 @@ int main(int argc, const char **argv) } if (monmap.fsid.is_zero()) { - cerr << argv[0] << ": generated monmap has no fsid; use '--fsid '" << std::endl; + derr << argv[0] << ": generated monmap has no fsid; use '--fsid '" << dendl; exit(10); } @@ -406,18 +409,21 @@ int main(int argc, const char **argv) if (osdmapfn.length()) { err = osdmapbl.read_file(osdmapfn.c_str(), &error); if (err < 0) { - cerr << argv[0] << ": error reading " << osdmapfn << ": " - << error << std::endl; + derr << argv[0] << ": error reading " << osdmapfn << ": " + << error << dendl; exit(1); } } // go MonitorDBStore store(g_conf->mon_data); - int r = store.create_and_open(cerr); + ostringstream oss; + int r = store.create_and_open(oss); + if (oss.tellp()) + derr << oss.str() << dendl; if (r < 0) { - cerr << argv[0] << ": error opening mon data directory at '" - << g_conf->mon_data << "': " << cpp_strerror(r) << std::endl; + derr << argv[0] << ": error opening mon data directory at '" + << g_conf->mon_data << "': " << cpp_strerror(r) << dendl; exit(1); } assert(r == 0); @@ -425,7 +431,7 @@ int main(int argc, const char **argv) Monitor mon(g_ceph_context, g_conf->name.get_id(), &store, 0, 0, &monmap); r = mon.mkfs(osdmapbl); if (r < 0) { - cerr << argv[0] << ": error creating monfs: " << cpp_strerror(r) << std::endl; + derr << argv[0] << ": error creating monfs: " << cpp_strerror(r) << dendl; exit(1); } store.close(); @@ -436,12 +442,12 @@ int main(int argc, const char **argv) err = check_mon_data_exists(); if (err < 0 && err == -ENOENT) { - cerr << "monitor data directory at '" << g_conf->mon_data << "'" - << " does not exist: have you run 'mkfs'?" << std::endl; + derr << "monitor data directory at '" << g_conf->mon_data << "'" + << " does not exist: have you run 'mkfs'?" << dendl; exit(1); } else if (err < 0) { - cerr << "error accessing monitor data directory at '" - << g_conf->mon_data << "': " << cpp_strerror(-err) << std::endl; + derr << "error accessing monitor data directory at '" + << g_conf->mon_data << "': " << cpp_strerror(-err) << dendl; exit(1); } @@ -452,8 +458,8 @@ int main(int argc, const char **argv) exit(1); } else if (err < 0 && err != -ENOTEMPTY) { // we don't want an empty data dir by now - cerr << "error accessing '" << g_conf->mon_data << "': " - << cpp_strerror(-err) << std::endl; + derr << "error accessing '" << g_conf->mon_data << "': " + << cpp_strerror(-err) << dendl; exit(1); } @@ -462,17 +468,17 @@ int main(int argc, const char **argv) ceph_data_stats_t stats; int err = get_fs_stats(stats, g_conf->mon_data.c_str()); if (err < 0) { - cerr << "error checking monitor data's fs stats: " << cpp_strerror(err) - << std::endl; + derr << "error checking monitor data's fs stats: " << cpp_strerror(err) + << dendl; exit(-err); } if (stats.avail_percent <= g_conf->mon_data_avail_crit) { - cerr << "error: monitor data filesystem reached concerning levels of" + derr << "error: monitor data filesystem reached concerning levels of" << " available storage space (available: " << stats.avail_percent << "% " << prettybyte_t(stats.byte_avail) << ")\nyou may adjust 'mon data avail crit' to a lower value" << " to make this go away (default: " << g_conf->mon_data_avail_crit - << "%)\n" << std::endl; + << "%)\n" << dendl; exit(ENOSPC); } } @@ -485,13 +491,13 @@ int main(int argc, const char **argv) string err_msg; err = prefork.prefork(err_msg); if (err < 0) { - cerr << err_msg << std::endl; + derr << err_msg << dendl; prefork.exit(err); } if (prefork.is_parent()) { err = prefork.parent_wait(err_msg); if (err < 0) - cerr << err_msg << std::endl; + derr << err_msg << dendl; prefork.exit(err); } global_init_postfork_start(g_ceph_context); @@ -507,11 +513,16 @@ int main(int argc, const char **argv) } MonitorDBStore *store = new MonitorDBStore(g_conf->mon_data); - err = store->open(std::cerr); - if (err < 0) { - derr << "error opening mon data directory at '" - << g_conf->mon_data << "': " << cpp_strerror(err) << dendl; - prefork.exit(1); + { + ostringstream oss; + err = store->open(oss); + if (oss.tellp()) + derr << oss.str() << dendl; + if (err < 0) { + derr << "error opening mon data directory at '" + << g_conf->mon_data << "': " << cpp_strerror(err) << dendl; + prefork.exit(1); + } } bufferlist magicbl; @@ -585,7 +596,7 @@ int main(int argc, const char **argv) try { monmap.decode(mapbl); } catch (const buffer::error& e) { - cerr << "can't decode monmap: " << e.what() << std::endl; + derr << "can't decode monmap: " << e.what() << dendl; } } else { derr << "unable to obtain a monmap: " << cpp_strerror(err) << dendl; @@ -633,7 +644,10 @@ int main(int argc, const char **argv) << ipaddr << dendl; } else { MonMap tmpmap; - int err = tmpmap.build_initial(g_ceph_context, cerr); + ostringstream oss; + int err = tmpmap.build_initial(g_ceph_context, oss); + if (oss.tellp()) + derr << oss.str() << dendl; if (err < 0) { derr << argv[0] << ": error generating initial monmap: " << cpp_strerror(err) << dendl; @@ -724,7 +738,10 @@ int main(int argc, const char **argv) if (force_sync) { derr << "flagging a forced sync ..." << dendl; - mon->sync_force(NULL, cerr); + ostringstream oss; + mon->sync_force(NULL, oss); + if (oss.tellp()) + derr << oss.str() << dendl; } err = mon->preinit(); -- 2.39.5