]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
objclass: implement 'osd class load list'
authorNoah Watkins <noahwatkins@gmail.com>
Mon, 27 Jun 2016 01:10:05 +0000 (18:10 -0700)
committerNoah Watkins <noahwatkins@gmail.com>
Mon, 27 Jun 2016 21:19:36 +0000 (14:19 -0700)
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
src/common/config_opts.h
src/osd/ClassHandler.cc
src/osd/ClassHandler.h
src/osd/OSD.cc
src/osd/ReplicatedPG.cc
src/vstart.sh

index 10d6a6b983cf6e5171b07e0de5c157c8c6681a24..21a9d378a1eb31c77cdb5db436c7939dbfdc318f 100644 (file)
@@ -775,6 +775,8 @@ OPTION(osd_deep_scrub_update_digest_min_age, OPT_INT, 2*60*60)   // objects must
 OPTION(osd_scan_list_ping_tp_interval, OPT_U64, 100)
 OPTION(osd_class_dir, OPT_STR, CEPH_LIBDIR "/rados-classes") // where rados plugins are stored
 OPTION(osd_open_classes_on_start, OPT_BOOL, true)
+OPTION(osd_class_load_list, OPT_STR, "cephfs hello journal lock log numops "
+    "rbd refcount replica_log rgw statelog timeindex user version") // list of object classes allowed to be loaded (allow all: *)
 OPTION(osd_check_for_log_corruption, OPT_BOOL, false)
 OPTION(osd_use_stale_snap, OPT_BOOL, false)
 OPTION(osd_rollback_to_cluster_snap, OPT_STR, "")
index 64b6c51febdb59b69d5da483dfd13418042664bd..d116f75ad897a59f81b4f3faf58edce01d6bbc7e 100644 (file)
@@ -29,7 +29,9 @@
 int ClassHandler::open_class(const string& cname, ClassData **pcls)
 {
   Mutex::Locker lock(mutex);
-  ClassData *cls = _get_class(cname);
+  ClassData *cls = _get_class(cname, true);
+  if (!cls)
+    return -EPERM;
   if (cls->status != ClassData::CLASS_OPEN) {
     int r = _load_class(cls);
     if (r)
@@ -60,8 +62,9 @@ int ClassHandler::open_all_classes()
       cname[strlen(cname) - (sizeof(CLS_SUFFIX) - 1)] = '\0';
       dout(10) << __func__ << " found " << cname << dendl;
       ClassData *cls;
+      // skip classes that aren't in 'osd class load list'
       r = open_class(cname, &cls);
-      if (r < 0)
+      if (r < 0 && r != -EPERM)
        goto out;
     }
   }
@@ -80,7 +83,33 @@ void ClassHandler::shutdown()
   classes.clear();
 }
 
-ClassHandler::ClassData *ClassHandler::_get_class(const string& cname)
+/*
+ * Check if @cname is in the whitespace delimited list @list, or the @list
+ * contains the wildcard "*".
+ *
+ * This is expensive but doesn't consume memory for an index, and is performed
+ * only once when a class is loaded.
+ */
+bool ClassHandler::in_class_list(const std::string& cname,
+    const std::string& list)
+{
+  std::istringstream ss(list);
+  std::istream_iterator<std::string> begin{ss};
+  std::istream_iterator<std::string> end{};
+
+  const std::vector<std::string> targets{cname, "*"};
+
+  auto it = std::find_first_of(begin, end,
+      targets.begin(), targets.end());
+
+  if (it == end)
+    return false;
+
+  return true;
+}
+
+ClassHandler::ClassData *ClassHandler::_get_class(const string& cname,
+    bool check_allowed)
 {
   ClassData *cls;
   map<string, ClassData>::iterator iter = classes.find(cname);
@@ -88,6 +117,10 @@ ClassHandler::ClassData *ClassHandler::_get_class(const string& cname)
   if (iter != classes.end()) {
     cls = &iter->second;
   } else {
+    if (check_allowed && !in_class_list(cname, cct->_conf->osd_class_load_list)) {
+      dout(0) << "_get_class not permitted to load " << cname << dendl;
+      return NULL;
+    }
     cls = &classes[cname];
     dout(10) << "_get_class adding new class name " << cname << " " << cls << dendl;
     cls->name = cname;
@@ -134,7 +167,7 @@ int ClassHandler::_load_class(ClassData *cls)
       while (deps) {
        if (!deps->name)
          break;
-       ClassData *cls_dep = _get_class(deps->name);
+       ClassData *cls_dep = _get_class(deps->name, false);
        cls->dependencies.insert(cls_dep);
        if (cls_dep->status != ClassData::CLASS_OPEN)
          cls->missing_dependencies.insert(cls_dep);
@@ -175,7 +208,7 @@ ClassHandler::ClassData *ClassHandler::register_class(const char *cname)
 {
   assert(mutex.is_locked());
 
-  ClassData *cls = _get_class(cname);
+  ClassData *cls = _get_class(cname, false);
   dout(10) << "register_class " << cname << " status " << cls->status << dendl;
 
   if (cls->status != ClassData::CLASS_INITIALIZING) {
index 74f5b69e7653b78076d77e568f7fe9a1be599497..6bdf6705052d80e36401e7e32ce9f802c13def17 100644 (file)
@@ -101,9 +101,12 @@ private:
   Mutex mutex;
   map<string, ClassData> classes;
 
-  ClassData *_get_class(const string& cname);
+  ClassData *_get_class(const string& cname, bool check_allowed);
   int _load_class(ClassData *cls);
 
+  bool in_class_list(const std::string& cname,
+      const std::string& list);
+
 public:
   explicit ClassHandler(CephContext *cct_) : cct(cct_), mutex("ClassHandler") {}
   
index 15e85ccedce8c98a49654cf6bfac2d117b55f8e3..f5ec2c505b5b4f0af31ef3afe9fa4ff6bd2a91fb 100644 (file)
@@ -9219,7 +9219,7 @@ int OSD::init_op_flags(OpRequestRef& op)
          derr << "class " << cname << " open got " << cpp_strerror(r) << dendl;
          if (r == -ENOENT)
            r = -EOPNOTSUPP;
-         else
+         else if (r != -EPERM) // propgate permission errors
            r = -EIO;
          return r;
        }
index f2695bc8082b3d23c4d0fb9f255ffff4df83229d..73d7ae3dd97f378201739e7b91bf33dff425d563 100644 (file)
@@ -629,7 +629,9 @@ int ReplicatedPG::get_pgls_filter(bufferlist::iterator& iter, PGLSFilter **pfilt
     if (r != 0) {
       derr << "Error opening class '" << class_name << "': "
            << cpp_strerror(r) << dendl;
-      return -EINVAL;
+      if (r != -EPERM) // propogate permission error
+        r = -EINVAL;
+      return r;
     } else {
       assert(cls);
     }
index b769a2388071849f705e13a48bb6d73e453d92c7..5f06abde559f667929f93c5e4a93e9bac698b79e 100755 (executable)
@@ -524,6 +524,7 @@ $DAEMONOPTS
         osd journal size = 100
         osd class tmp = out
         osd class dir = $OBJCLASS_PATH
+        osd class load list = *
         osd scrub load threshold = 2000.0
         osd debug op order = true
         filestore wbthrottle xfs ios start flusher = 10