]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools: New "removeall" used to remove head with snapshots
authorDavid Zafman <dzafman@redhat.com>
Fri, 1 Jul 2016 06:18:03 +0000 (23:18 -0700)
committerDavid Zafman <dzafman@redhat.com>
Wed, 27 Jul 2016 16:58:59 +0000 (09:58 -0700)
Use --force to allow remove to only remove head object
Adding testing to unit test

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

index 041f7e3d6604bd1b55c8e07f491f79dd09b9acd1..2e2e12d5163fd9a05ea711b8291409672f624768 100755 (executable)
@@ -577,6 +577,75 @@ def test_get_set_inc_osdmap(CFSD_PREFIX, osd_path):
     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":
@@ -1868,6 +1937,8 @@ def main(argv):
     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])
index 55f873501d040d362a619f4326dd832ab29f146e..9b378bfcda53176b359e854020600d00e93170e3 100755 (executable)
@@ -98,7 +98,7 @@ function TEST_scrub_snaps() {
     # 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
index 9937335f64e6369b2b962857b688b6f1c894a2df..7488a25e5006b0681ba03f556480c849e6cdfc5d 100644 (file)
@@ -1429,8 +1429,25 @@ int do_meta(ObjectStore *store, string object, Formatter *formatter, bool debug,
   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;
@@ -1448,20 +1465,52 @@ int do_remove_object(ObjectStore *store, coll_t coll,
     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;
 }
 
@@ -2160,7 +2209,7 @@ void usage(po::options_description &desc)
     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;
@@ -2838,8 +2887,9 @@ int main(int argc, char **argv)
 
     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);