From a2806854059e06db8a149c1e6a17bd0c826ae517 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Wed, 6 Oct 2010 12:09:00 -0700 Subject: [PATCH] osd: save corrupt pg_logs to a special collection If the PG log is corrupt when we start up, save it to a special collection so that we can examine it later. Signed-off-by: Colin McCabe --- src/osd/PG.cc | 32 +++++++++++++++++++++++++++++--- src/osd/PG.h | 1 + src/osd/osd_types.h | 2 +- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 4d0f0ae681634..d8cda15febe3e 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -35,7 +35,7 @@ #define DOUT_SUBSYS osd #undef dout_prefix #define dout_prefix _prefix(this, osd->whoami, osd->osdmap) -static ostream& _prefix(PG *pg, int whoami, OSDMap *osdmap) { +static ostream& _prefix(const PG *pg, int whoami, OSDMap *osdmap) { return *_dout << dbeginl << "osd" << whoami << " " << (osdmap ? osdmap->get_epoch():0) << " " << *pg << " "; } @@ -2379,7 +2379,22 @@ bool PG::check_log_for_corruption(ObjectStore *store) return ok; } - +//! Get the name we're going to save our corrupt page log as +std::string PG::get_corrupt_pg_log_name() const +{ + const int MAX_BUF = 512; + char buf[MAX_BUF]; + struct tm tm_buf; + time_t my_time(time(NULL)); + const struct tm *t = localtime_r(&my_time, &tm_buf); + int ret = strftime(buf, sizeof(buf), "corrupt_log_%Y-%m-%d_%k:%M_", t); + if (ret == 0) { + dout(0) << "strftime failed" << dendl; + return "corrupt_log_unknown_time"; + } + info.pgid.print(buf + ret, MAX_BUF - ret); + return buf; +} void PG::read_state(ObjectStore *store) { @@ -2406,8 +2421,19 @@ void PG::read_state(ObjectStore *store) } catch (const buffer::error &e) { // Pretend that there is no ondisklog + string cr_log_coll_name(get_corrupt_pg_log_name()); dout(0) << "Got exception '" << e.what() << "' while reading log. " - << "Zeroing log." << dendl; + << "Moving corrupted log file to '" << cr_log_coll_name + << "' for later " << "analysis." << dendl; + ObjectStore::Transaction t; + coll_t cr_log_coll(cr_log_coll_name); + t.create_collection(cr_log_coll); + t.collection_add(cr_log_coll, coll_t::META_COLL, log_oid); + t.collection_remove(coll_t::META_COLL, log_oid); + t.touch(coll_t::META_COLL, log_oid); + store->apply_transaction(t); + + // clear the log ondisklog.zero(); log.head = log.tail = info.last_update; info.log_tail = info.last_update; diff --git a/src/osd/PG.h b/src/osd/PG.h index a1b9ae946a095..0856942febb6e 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -995,6 +995,7 @@ public: void trim_ondisklog_to(ObjectStore::Transaction& t, eversion_t v); void trim_peers(); + std::string get_corrupt_pg_log_name() const; void read_state(ObjectStore *store); coll_t make_snap_collection(ObjectStore::Transaction& t, snapid_t sn); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 88fc9833fc626..761edf6774c5a 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -141,7 +141,7 @@ struct pg_t { return coll_t(u.pg64, sn); }*/ - int print(char *o, int maxlen) { + int print(char *o, int maxlen) const { if (preferred() >= 0) return snprintf(o, maxlen, "%d.%xp%d", pool(), ps(), preferred()); else -- 2.39.5