]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-objectstore-tool: Add undocumented clear-snapset command for testing
authorDavid Zafman <dzafman@redhat.com>
Thu, 8 Oct 2015 00:25:44 +0000 (17:25 -0700)
committerDavid Zafman <dzafman@redhat.com>
Fri, 30 Oct 2015 20:01:50 +0000 (13:01 -0700)
Add test cases using new feature to corrupt SnapSet

Signed-off-by: David Zafman <dzafman@redhat.com>
src/test/osd/osd-scrub-snaps.sh
src/tools/ceph_objectstore_tool.cc

index 51f08c8d7c6b086d7b06bd4679fbcdb94962c54b..fbc93be8f446d2b896cba5f3cad7bbfe6b500c3d 100755 (executable)
@@ -27,7 +27,7 @@ wait_for_health
 ./ceph osd pool create test 1 1
 
 dd if=/dev/urandom of=$TESTDATA bs=1032 count=1
-for i in `seq 1 5`
+for i in `seq 1 14`
 do
     ./rados -p test put obj${i} $TESTDATA
 done
@@ -38,6 +38,9 @@ dd if=/dev/urandom of=$TESTDATA bs=256 count=${SNAP}
 ./rados -p test put obj1 $TESTDATA
 ./rados -p test put obj5 $TESTDATA
 ./rados -p test put obj3 $TESTDATA
+for i in `seq 6 14`
+ do ./rados -p test put obj${i} $TESTDATA
+done
 
 SNAP=2
 ./rados -p test mksnap snap${SNAP}
@@ -102,6 +105,25 @@ dd if=/dev/urandom of=$TESTDATA bs=256 count=7
 
 rm -f $TESTDATA
 
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj6 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj7 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset corrupt
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj8 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset seq
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj9 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset clone_size
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj10 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset clone_overlap
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj11 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset clones
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj12 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset head
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj13 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset snaps
+JSON="$(./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal --op list obj14 | grep \"snapid\":-2)"
+./ceph-objectstore-tool --data-path dev/osd0 --journal-path dev/osd0.journal "$JSON" clear-snapset size
+
 #MDS=0 MON=1 OSD=1 ./vstart.sh -l -d  -o "osd_pool_default_size=1"
 ./ceph-osd -i 0 -c ceph.conf
 wait_for_health
@@ -115,20 +137,30 @@ timeout 30 ./ceph -w
 ERRORS=0
 
 declare -a err_strings
-err_strings[0]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/6cf8deff/obj1/1 is an unexpected clone"
+err_strings[0]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/2acecc8b/obj10/1 is missing in clone_overlap"
 err_strings[1]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/7 no '_' attr"
 err_strings[2]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/7 is an unexpected clone"
-err_strings[3]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/head expected clone 1/666934a3/obj5/2"
-err_strings[4]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/head expected clone 1/666934a3/obj5/1"
-err_strings[5]="log_channel[(]cluster[)] log [[]INF[]] : scrub 1.0 1/666934a3/obj5/head missing clones"
-err_strings[6]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/3f1ee208/obj2/snapdir no 'snapset' attr"
-err_strings[7]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/3f1ee208/obj2/7 is an unexpected clone"
-err_strings[8]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/3f1ee208/obj2/4 is an unexpected clone"
-err_strings[9]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/a8759770/obj4/snapdir expected clone 1/a8759770/obj4/7"
-err_strings[10]="log_channel[(]cluster[)] log [[]INF[]] : scrub 1.0 1/a8759770/obj4/snapdir missing clones"
-err_strings[11]="log_channel[(]cluster[)] log [[]ERR[]] : 1.0 scrub 12 errors"
-err_strings[12]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/4 on disk size [(]4608[)] does not match object info size [(]512[)] adjusted for ondisk to [(]512[)]"
-err_strings[13]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/61f68bb1/obj3/head on disk size [(]3840[)] does not match object info size [(]768[)] adjusted for ondisk to [(]768[)]"
+err_strings[3]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/4 on disk size [(]4608[)] does not match object info size [(]512[)] adjusted for ondisk to [(]512[)]"
+err_strings[4]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/head expected clone 1/666934a3/obj5/2"
+err_strings[5]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/666934a3/obj5/head expected clone 1/666934a3/obj5/1"
+err_strings[6]="log_channel[(]cluster[)] log [[]INF[]] : scrub 1.0 1/666934a3/obj5/head missing clones"
+err_strings[7]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/d3a9faf5/obj12/head snapset.head_exists=false, but head exists"
+err_strings[8]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/7c6b5865/obj13/head snaps empty"
+err_strings[9]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/8df7eaa5/obj8/head snaps.seq not set"
+err_strings[10]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/5c889059/obj7/head snapset.head_exists=false, but head exists"
+err_strings[11]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/5c889059/obj7/1 is an unexpected clone"
+err_strings[12]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/61f68bb1/obj3/head on disk size [(]3840[)] does not match object info size [(]768[)] adjusted for ondisk to [(]768[)]"
+err_strings[13]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/83425cc4/obj6/1 is an unexpected clone"
+err_strings[14]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/3f1ee208/obj2/snapdir no 'snapset' attr"
+err_strings[15]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/3f1ee208/obj2/7 is an unexpected clone"
+err_strings[16]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/3f1ee208/obj2/4 is an unexpected clone"
+err_strings[17]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/a8759770/obj4/snapdir expected clone 1/a8759770/obj4/7"
+err_strings[18]="log_channel[(]cluster[)] log [[]INF[]] : scrub 1.0 1/a8759770/obj4/snapdir missing clones"
+err_strings[19]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/6cf8deff/obj1/1 is an unexpected clone"
+err_strings[20]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/e478ac7f/obj9/1 is missing in clone_size"
+err_strings[21]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/29547577/obj11/1 is an unexpected clone"
+err_strings[22]="log_channel[(]cluster[)] log [[]ERR[]] : scrub 1.0 1/94122507/obj14/1 size 1032 != clone_size 1033"
+err_strings[23]="log_channel[(]cluster[)] log [[]ERR[]] : 1.0 scrub 22 errors"
 
 for i in `seq 0 ${#err_strings[@]}`
 do
index d58c427d3dc4dd1205f90a9b1b7048c73e3ee4c6..2977e3920b452767fe2d613b0fbedfb158b88f50 100644 (file)
@@ -2021,6 +2021,60 @@ int set_size(ObjectStore *store, coll_t coll, ghobject_t &ghobj, uint64_t setsiz
   return 0;
 }
 
+int clear_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj,
+                  string arg, ObjectStore::Sequencer &osr)
+{
+  SnapSet ss;
+  int ret = get_snapset(store, coll, ghobj, ss);
+  if (ret < 0)
+    return ret;
+
+  // Use "head" to set head_exists incorrectly
+  if (arg == "corrupt" || arg == "head")
+    ss.head_exists = !ghobj.hobj.is_head();
+  else if (ss.head_exists != ghobj.hobj.is_head()) {
+    cerr << "Correcting head_exists, set to "
+         << (ghobj.hobj.is_head() ? "true" : "false") << std::endl;
+    ss.head_exists = ghobj.hobj.is_head();
+  }
+  // Use "corrupt" to clear entire SnapSet
+  // Use "seq" to just corrupt SnapSet.seq
+  if (arg == "corrupt" || arg == "seq")
+    ss.seq = 0;
+  // Use "snaps" to just clear SnapSet.snaps
+  if (arg == "corrupt" || arg == "snaps")
+    ss.snaps.clear();
+  // By default just clear clone, clone_overlap and clone_size
+  if (arg == "corrupt")
+    arg = "";
+  if (arg == "" || arg == "clones")
+    ss.clones.clear();
+  if (arg == "" || arg == "clone_overlap")
+    ss.clone_overlap.clear();
+  if (arg == "" || arg == "clone_size")
+    ss.clone_size.clear();
+  // Break all clone sizes by adding 1
+  if (arg == "size") {
+    for (map<snapid_t, uint64_t>::iterator i = ss.clone_size.begin();
+         i != ss.clone_size.end(); ++i)
+      ++(i->second);
+  }
+
+  if (!dry_run) {
+    bufferlist bl;
+    ::encode(ss, bl);
+    ObjectStore::Transaction t;
+    t.setattr(coll, ghobj, SS_ATTR, bl);
+    int r = store->apply_transaction(&osr, t);
+    if (r < 0) {
+      cerr << "Error setting snapset on : " << make_pair(coll, ghobj) << ", "
+          << cpp_strerror(r) << std::endl;
+      return r;
+    }
+  }
+  return 0;
+}
+
 void usage(po::options_description &desc)
 {
     cerr << std::endl;
@@ -2966,6 +3020,16 @@ int main(int argc, char **argv)
        uint64_t size = atoll(arg1.c_str());
        ret = set_size(fs, coll, ghobj, size, formatter, *osr);
        goto out;
+      } else if (objcmd == "clear-snapset") {
+        // UNDOCUMENTED: For testing zap SnapSet
+        // IGNORE extra args since not in usage anyway
+       if (!ghobj.hobj.has_snapset()) {
+         cerr << "'" << objcmd << "' requires a head or snapdir object" << std::endl;
+         ret = 1;
+         goto out;
+       }
+        ret = clear_snapset(fs, coll, ghobj, arg1, *osr);
+        goto out;
       }
       cerr << "Unknown object command '" << objcmd << "'" << std::endl;
       usage(desc);