return errors
+def test_removeall(CFSD_PREFIX, db, OBJREPPGS, REP_POOL, CEPH_BIN, OSDDIR, REP_NAME, NUM_CLONED_REP_OBJECTS):
+ # Test removeall
+ TMPFILE = r"/tmp/tmp.{pid}".format(pid=os.getpid())
+ nullfd = open(os.devnull, "w")
+ errors=0
+ print "Test removeall"
+ kill_daemons()
+ for nspace in db.keys():
+ for basename in db[nspace].keys():
+ JSON = db[nspace][basename]['json']
+ for pg in OBJREPPGS:
+ OSDS = get_osds(pg, OSDDIR)
+ for osd in OSDS:
+ DIR = os.path.join(OSDDIR, os.path.join(osd, os.path.join("current", "{pg}_head".format(pg=pg))))
+ fnames = [f for f in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, f))
+ and f.split("_")[0] == basename and f.split("_")[4] == nspace]
+ if not fnames:
+ continue
+
+ if int(basename.split(REP_NAME)[1]) <= int(NUM_CLONED_REP_OBJECTS):
+ cmd = (CFSD_PREFIX + "'{json}' remove").format(osd=osd, json=JSON)
+ errors += test_failure(cmd, "Snapshots are present, use removeall to delete everything")
+
+ cmd = (CFSD_PREFIX + " --force --dry-run '{json}' remove").format(osd=osd, json=JSON)
+ logging.debug(cmd)
+ ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
+ if ret != 0:
+ logging.error("remove with --force failed for {json}".format(json=JSON))
+ errors += 1
+
+ cmd = (CFSD_PREFIX + " --dry-run '{json}' removeall").format(osd=osd, json=JSON)
+ logging.debug(cmd)
+ ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
+ if ret != 0:
+ logging.error("removeall failed for {json}".format(json=JSON))
+ errors += 1
+
+ cmd = (CFSD_PREFIX + " '{json}' removeall").format(osd=osd, json=JSON)
+ logging.debug(cmd)
+ ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
+ if ret != 0:
+ logging.error("removeall failed for {json}".format(json=JSON))
+ errors += 1
+
+ tmpfd = open(TMPFILE, "w")
+ cmd = (CFSD_PREFIX + "--op list --pgid {pg} --namespace {ns} {name}").format(osd=osd, pg=pg, ns=nspace, name=basename)
+ logging.debug(cmd)
+ ret = call(cmd, shell=True, stdout=tmpfd)
+ if ret != 0:
+ logging.error("Bad exit status {ret} from {cmd}".format(ret=ret, cmd=cmd))
+ errors += 1
+ tmpfd.close()
+ lines = get_lines(TMPFILE)
+ if len(lines) != 0:
+ logging.error("Removeall didn't remove all objects {ns}/{name} : {lines}".format(ns=nspace, name=basename, lines=lines))
+ errors += 1
+ vstart(new=False)
+ wait_for_health()
+ cmd = "{path}/rados -p {pool} rmsnap snap1".format(pool=REP_POOL, path=CEPH_BIN)
+ logging.debug(cmd)
+ ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
+ if ret != 0:
+ logging.error("rados rmsnap failed")
+ errors += 1
+ time.sleep(2)
+ wait_for_health()
+ return errors
+
+
def main(argv):
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
if len(argv) > 1 and argv[1] == "debug":
call("/bin/rm -rf {dir}".format(dir=TESTDIR), shell=True)
call("/bin/rm -rf {dir}".format(dir=DATADIR), shell=True)
+ ERRORS += test_removeall(CFSD_PREFIX, db, OBJREPPGS, REP_POOL, CEPH_BIN, OSDDIR, REP_NAME, NUM_CLONED_REP_OBJECTS)
+
# vstart() starts 4 OSDs
ERRORS += test_get_set_osdmap(CFSD_PREFIX, range(4), ALLOSDS)
ERRORS += test_get_set_inc_osdmap(CFSD_PREFIX, ALLOSDS[0])
# Don't need to ceph_objectstore_tool function because osd stopped
JSON="$(ceph-objectstore-tool --data-path $dir/0 --journal-path $dir/0/journal --op list obj1 | grep \"snapid\":-2)"
- ceph-objectstore-tool --data-path $dir/0 --journal-path $dir/0/journal "$JSON" remove
+ ceph-objectstore-tool --data-path $dir/0 --journal-path $dir/0/journal "$JSON" --force remove
JSON="$(ceph-objectstore-tool --data-path $dir/0 --journal-path $dir/0/journal --op list obj5 | grep \"snapid\":2)"
ceph-objectstore-tool --data-path $dir/0 --journal-path $dir/0/journal "$JSON" remove
return 0;
}
+int remove_object(coll_t coll, ghobject_t &ghobj,
+ SnapMapper &mapper,
+ MapCacher::Transaction<std::string, bufferlist> *_t,
+ ObjectStore::Transaction *t)
+{
+ int r = mapper.remove_oid(ghobj.hobj, _t);
+ if (r < 0 && r != -ENOENT) {
+ cerr << "remove_oid returned " << cpp_strerror(r) << std::endl;
+ return r;
+ }
+
+ t->remove(coll, ghobj);
+ return 0;
+}
+
+int get_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj, SnapSet &ss, bool silent);
+
int do_remove_object(ObjectStore *store, coll_t coll,
- ghobject_t &ghobj,
+ ghobject_t &ghobj, bool all, bool force,
ObjectStore::Sequencer &osr)
{
spg_t pg;
return r;
}
- cout << "remove " << ghobj << std::endl;
- if (dry_run)
- return 0;
+ SnapSet ss;
+ if (ghobj.hobj.has_snapset()) {
+ r = get_snapset(store, coll, ghobj, ss, false);
+ if (r < 0) {
+ cerr << "Can't get snapset error " << cpp_strerror(r) << std::endl;
+ return r;
+ }
+ if (!ss.snaps.empty() && !all) {
+ if (force) {
+ cout << "WARNING: only removing "
+ << (ghobj.hobj.is_head() ? "head" : "snapdir")
+ << " with snapshots present" << std::endl;
+ ss.snaps.clear();
+ } else {
+ cerr << "Snapshots are present, use removeall to delete everything" << std::endl;
+ return -EINVAL;
+ }
+ }
+ }
+
ObjectStore::Transaction t;
OSDriver::OSTransaction _t(driver.get_transaction(&t));
- r = mapper.remove_oid(ghobj.hobj, &_t);
- if (r < 0 && r != -ENOENT) {
- cerr << "remove_oid returned " << cpp_strerror(r) << std::endl;
- return r;
+
+ cout << "remove " << ghobj << std::endl;
+
+ if (!dry_run) {
+ r = remove_object(coll, ghobj, mapper, &_t, &t);
+ if (r < 0)
+ return r;
+ }
+
+ ghobject_t snapobj = ghobj;
+ for (vector<snapid_t>::iterator i = ss.snaps.begin() ;
+ i != ss.snaps.end() ; ++i) {
+ snapobj.hobj.snap = *i;
+ cout << "remove " << snapobj << std::endl;
+ if (!dry_run) {
+ r = remove_object(coll, snapobj, mapper, &_t, &t);
+ if (r < 0)
+ return r;
+ }
}
- t.remove(coll, ghobj);
+ if (!dry_run)
+ store->apply_transaction(&osr, std::move(t));
- store->apply_transaction(&osr, std::move(t));
return 0;
}
cerr << "ceph-objectstore-tool ... <object> set-omaphdr [file]" << std::endl;
cerr << "ceph-objectstore-tool ... <object> list-attrs" << std::endl;
cerr << "ceph-objectstore-tool ... <object> list-omap" << std::endl;
- cerr << "ceph-objectstore-tool ... <object> remove" << std::endl;
+ cerr << "ceph-objectstore-tool ... <object> remove|removeall" << std::endl;
cerr << "ceph-objectstore-tool ... <object> dump" << std::endl;
cerr << "ceph-objectstore-tool ... <object> set-size" << std::endl;
cerr << "ceph-objectstore-tool ... <object> remove-clone-metadata <cloneid>" << std::endl;
if (vm.count("objcmd")) {
ret = 0;
- if (objcmd == "remove") {
- ret = do_remove_object(fs, coll, ghobj, *osr);
+ if (objcmd == "remove" || objcmd == "removeall") {
+ bool all = (objcmd == "removeall");
+ ret = do_remove_object(fs, coll, ghobj, all, force, *osr);
goto out;
} else if (objcmd == "list-attrs") {
ret = do_list_attrs(fs, coll, ghobj);