From: Noah Watkins Date: Mon, 27 Jun 2016 01:10:05 +0000 (-0700) Subject: objclass: implement 'osd class load list' X-Git-Tag: ses5-milestone5~384^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e71e2491877362e53e0e93223940df101f0ccf39;p=ceph.git objclass: implement 'osd class load list' Signed-off-by: Noah Watkins --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 10d6a6b983cf..21a9d378a1eb 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -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, "") diff --git a/src/osd/ClassHandler.cc b/src/osd/ClassHandler.cc index 64b6c51febdb..d116f75ad897 100644 --- a/src/osd/ClassHandler.cc +++ b/src/osd/ClassHandler.cc @@ -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 begin{ss}; + std::istream_iterator end{}; + + const std::vector 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::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) { diff --git a/src/osd/ClassHandler.h b/src/osd/ClassHandler.h index 74f5b69e7653..6bdf6705052d 100644 --- a/src/osd/ClassHandler.h +++ b/src/osd/ClassHandler.h @@ -101,9 +101,12 @@ private: Mutex mutex; map 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") {} diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 15e85ccedce8..f5ec2c505b5b 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -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; } diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index f2695bc8082b..73d7ae3dd97f 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -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); } diff --git a/src/vstart.sh b/src/vstart.sh index b769a2388071..5f06abde559f 100755 --- a/src/vstart.sh +++ b/src/vstart.sh @@ -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