./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
./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}
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
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
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;
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);