]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: save corrupt pg_logs to a special collection
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Wed, 6 Oct 2010 19:09:00 +0000 (12:09 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Wed, 6 Oct 2010 20:05:04 +0000 (13:05 -0700)
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 <colinm@hq.newdream.net>
src/osd/PG.cc
src/osd/PG.h
src/osd/osd_types.h

index 4d0f0ae681634e5e09ad5f10731602ad8dc89b51..d8cda15febe3e6d2853706f384eef9a1747bcbb4 100644 (file)
@@ -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;
index a1b9ae946a09592e90c7a029e0ee76c0d2d87c05..0856942febb6e9a893a1932e0e10940779719e73 100644 (file)
@@ -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);
 
index 88fc9833fc626bd25b2afcdd078fd8063224b237..761edf6774c5a545947baeffde7a1eb27c736204 100644 (file)
@@ -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