From a140439f85a64820c5a852c30115ef61929a7326 Mon Sep 17 00:00:00 2001 From: John Spray Date: Wed, 10 Sep 2014 14:01:54 +0100 Subject: [PATCH] mds: limit number of caps inspected in caps_tick This is to avoid hitting an O(caps) loop in the worst cast scenario. This mechanism is a little crude but should be superceded at some point by admin socket functionality to inspect session caps so that we don't need to spit out this level of detail in logs. Signed-off-by: John Spray --- src/mds/Locker.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index d1d69f359e6..c76582255c8 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -3254,6 +3254,10 @@ void Locker::get_late_revoking_clients(std::list *result) const } } +// Hard-code instead of surfacing a config settings because this is +// really a hack that should go away at some point when we have better +// inspection tools for getting at detailed cap state (#7316) +#define MAX_WARN_CAPS 100 void Locker::caps_tick() { @@ -3261,6 +3265,7 @@ void Locker::caps_tick() dout(20) << __func__ << " " << revoking_caps.size() << " revoking caps" << dendl; + int i = 0; for (xlist::iterator p = revoking_caps.begin(); !p.end(); ++p) { Capability *cap = *p; @@ -3269,6 +3274,13 @@ void Locker::caps_tick() if (age <= g_conf->mds_revoke_cap_timeout) { dout(20) << __func__ << " age below timeout " << g_conf->mds_revoke_cap_timeout << dendl; break; + } else { + ++i; + if (i > MAX_WARN_CAPS) { + dout(1) << __func__ << " more than " << MAX_WARN_CAPS << " caps are late" + << "revoking, ignoring subsequent caps" << dendl; + break; + } } // exponential backoff of warning intervals if (age > g_conf->mds_revoke_cap_timeout * (1 << cap->get_num_revoke_warnings())) { -- 2.47.3