summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.git_version4
-rw-r--r--src/client/Client.cc8
-rw-r--r--src/client/Client.h2
-rw-r--r--src/common/ceph_strings.cc6
-rw-r--r--src/common/options/mds-client.yaml.in8
-rw-r--r--src/mds/Beacon.cc24
-rw-r--r--src/mds/MDSAuthCaps.h17
-rw-r--r--src/mds/Server.cc23
-rw-r--r--src/mds/SessionMap.cc1
-rw-r--r--src/mds/SessionMap.h12
-rw-r--r--src/mds/mdstypes.cc26
-rw-r--r--src/mds/mdstypes.h3
-rw-r--r--src/messages/MMDSBeacon.h5
-rw-r--r--src/mon/MDSMonitor.cc1
-rw-r--r--src/osd/OSDMap.cc8
-rw-r--r--src/pybind/mgr/k8sevents/module.py18
-rw-r--r--src/pybind/mgr/requirements.txt2
17 files changed, 133 insertions, 35 deletions
diff --git a/src/.git_version b/src/.git_version
index 32a4fa347..1c10e47ef 100644
--- a/src/.git_version
+++ b/src/.git_version
@@ -1,2 +1,2 @@
-76424b2fe1bb19c32c52140f39764599abf5e035
-18.2.3
+e7ad5345525c7aa95470c26863873b581076945d
+18.2.4
diff --git a/src/client/Client.cc b/src/client/Client.cc
index ba41e9dd0..ec97e36fb 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -392,6 +392,12 @@ Client::Client(Messenger *m, MonClient *mc, Objecter *objecter_)
if (cct->_conf->client_acl_type == "posix_acl")
acl_type = POSIX_ACL;
+ if (auto str = cct->_conf->client_debug_inject_features; !str.empty()) {
+ myfeatures = feature_bitset_t(str);
+ } else {
+ myfeatures = feature_bitset_t(CEPHFS_FEATURES_CLIENT_SUPPORTED);
+ }
+
lru.lru_set_midpoint(cct->_conf->client_cache_mid);
// file handles
@@ -2354,7 +2360,7 @@ MetaSessionRef Client::_open_mds_session(mds_rank_t mds)
auto m = make_message<MClientSession>(CEPH_SESSION_REQUEST_OPEN);
m->metadata = metadata;
- m->supported_features = feature_bitset_t(CEPHFS_FEATURES_CLIENT_SUPPORTED);
+ m->supported_features = myfeatures;
m->metric_spec = feature_bitset_t(CEPHFS_METRIC_FEATURES_ALL);
session->con->send_message2(std::move(m));
return session;
diff --git a/src/client/Client.h b/src/client/Client.h
index beeef0803..dc9e31aa8 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -1639,6 +1639,8 @@ private:
uint64_t nr_write_request = 0;
std::vector<MDSCapAuth> cap_auths;
+
+ feature_bitset_t myfeatures;
};
/**
diff --git a/src/common/ceph_strings.cc b/src/common/ceph_strings.cc
index 18dcc701b..a92311618 100644
--- a/src/common/ceph_strings.cc
+++ b/src/common/ceph_strings.cc
@@ -151,7 +151,11 @@ uint64_t ceph_release_features(int r)
return req;
req |= CEPH_FEATUREMASK_CRUSH_CHOOSE_ARGS; // and overlaps
- if (r <= CEPH_RELEASE_LUMINOUS)
+ if (r <= CEPH_RELEASE_QUINCY)
+ return req;
+
+ req |= CEPH_FEATUREMASK_SERVER_REEF; // upmap-primary
+ if (r <= CEPH_RELEASE_REEF)
return req;
return req;
diff --git a/src/common/options/mds-client.yaml.in b/src/common/options/mds-client.yaml.in
index 1f7600dee..28912cdb1 100644
--- a/src/common/options/mds-client.yaml.in
+++ b/src/common/options/mds-client.yaml.in
@@ -251,6 +251,14 @@ options:
default: 0
services:
- mds_client
+- name: client_debug_inject_features
+ type: str
+ level: dev
+ services:
+ - mds_client
+ flags:
+ - startup
+ with_legacy: true
- name: client_max_inline_size
type: size
level: dev
diff --git a/src/mds/Beacon.cc b/src/mds/Beacon.cc
index 5dd319a14..b67e0a31b 100644
--- a/src/mds/Beacon.cc
+++ b/src/mds/Beacon.cc
@@ -484,6 +484,30 @@ void Beacon::notify_health(MDSRank const *mds)
health.metrics.push_back(m);
}
+ // Report a health warning if clients have broken root_squash
+ if (auto c = mds->sessionmap.num_broken_root_squash_clients(); c > 0) {
+ std::vector<MDSHealthMetric> metrics;
+
+ for (auto&& session : mds->sessionmap.get_broken_root_squash_clients()) {
+ CachedStackStringStream css;
+ *css << "Client " << session->get_human_name() << " has broken root_squash implementation";
+ MDSHealthMetric m(MDS_HEALTH_CLIENTS_BROKEN_ROOTSQUASH, HEALTH_ERR, css->strv());
+ m.metadata["client_id"] = stringify(session->get_client());
+ metrics.emplace_back(std::move(m));
+ }
+
+ if (metrics.size() <= (size_t)g_conf()->mds_health_summarize_threshold) {
+ health.metrics.insert(std::end(health.metrics), std::make_move_iterator(std::begin(metrics)), std::make_move_iterator(std::end(metrics)));
+ } else {
+ CachedStackStringStream css;
+ *css << "There are " << c << " clients with broken root_squash implementations";
+ dout(20) << css->strv() << dendl;
+ MDSHealthMetric m(MDS_HEALTH_CLIENTS_BROKEN_ROOTSQUASH, HEALTH_ERR, css->strv());
+ m.metadata["client_count"] = stringify(c);
+ health.metrics.push_back(std::move(m));
+ }
+ }
+
// Report if we have significantly exceeded our cache size limit
if (mds->mdcache->cache_overfull()) {
CachedStackStringStream css;
diff --git a/src/mds/MDSAuthCaps.h b/src/mds/MDSAuthCaps.h
index bbb2589b3..f77fd965a 100644
--- a/src/mds/MDSAuthCaps.h
+++ b/src/mds/MDSAuthCaps.h
@@ -146,6 +146,10 @@ struct MDSCapMatch {
*/
bool match_path(std::string_view target_path) const;
+ bool match_fs(std::string_view target_fs) const {
+ return fs_name == target_fs || fs_name.empty() || fs_name == "*";
+ }
+
void encode(ceph::buffer::list& bl) const {
ENCODE_START(1, 1, bl);
encode(uid, bl);
@@ -261,8 +265,7 @@ public:
}
for (const MDSCapGrant &g : grants) {
- if (g.match.fs_name == fs_name || g.match.fs_name.empty() ||
- g.match.fs_name == "*") {
+ if (g.match.match_fs(fs_name)) {
if (mask & MAY_READ && g.spec.allow_read()) {
return true;
}
@@ -285,10 +288,12 @@ public:
}
}
- bool root_squash_in_caps() const {
- for (const MDSCapGrant &g : grants) {
- if (g.match.root_squash) {
- return true;
+ bool root_squash_in_caps(std::string_view fs_name) const {
+ for (const MDSCapGrant& g : grants) {
+ if (g.match.match_fs(fs_name)) {
+ if (g.match.root_squash) {
+ return true;
+ }
}
}
return false;
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index 48e7b03ae..2f8b376ce 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -717,16 +717,10 @@ void Server::handle_client_session(const cref_t<MClientSession> &m)
break;
}
- if (session->auth_caps.root_squash_in_caps() && !client_metadata.features.test(CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK)) {
- CachedStackStringStream css;
- *css << "client lacks CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK needed to enforce 'root_squash' MDS auth caps";
- send_reject_message(css->strv());
- mds->clog->warn() << "client session (" << session->info.inst
- << ") lacks CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK "
- << " needed to enforce 'root_squash' MDS auth caps";
- session->clear();
- break;
-
+ std::string_view fs_name = mds->mdsmap->get_fs_name();
+ bool client_caps_check = client_metadata.features.test(CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK);
+ if (session->auth_caps.root_squash_in_caps(fs_name) && !client_caps_check) {
+ mds->sessionmap.add_to_broken_root_squash_clients(session);
}
// Special case for the 'root' metadata path; validate that the claimed
// root is actually within the caps of the session
@@ -1573,11 +1567,10 @@ void Server::handle_client_reconnect(const cref_t<MClientReconnect> &m)
*css << "missing required features '" << missing_features << "'";
error_str = css->strv();
}
- if (session->auth_caps.root_squash_in_caps() &&
- !session->info.client_metadata.features.test(CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK)) {
- CachedStackStringStream css;
- *css << "client lacks CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK needed to enforce 'root_squash' MDS auth caps";
- error_str = css->strv();
+ std::string_view fs_name = mds->mdsmap->get_fs_name();
+ bool client_caps_check = session->info.client_metadata.features.test(CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK);
+ if (session->auth_caps.root_squash_in_caps(fs_name) && !client_caps_check) {
+ mds->sessionmap.add_to_broken_root_squash_clients(session);
}
}
diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc
index 9cc2b0138..9bec67c24 100644
--- a/src/mds/SessionMap.cc
+++ b/src/mds/SessionMap.cc
@@ -705,6 +705,7 @@ void SessionMap::remove_session(Session *s)
s->trim_completed_requests(0);
s->item_session_list.remove_myself();
+ broken_root_squash_clients.erase(s);
session_map.erase(s->info.inst.name);
dirty_sessions.erase(s->info.inst.name);
null_sessions.insert(s->info.inst.name);
diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h
index 360dd66a2..623f20a0e 100644
--- a/src/mds/SessionMap.h
+++ b/src/mds/SessionMap.h
@@ -682,6 +682,16 @@ public:
void remove_session(Session *s);
void touch_session(Session *session);
+ void add_to_broken_root_squash_clients(Session* s) {
+ broken_root_squash_clients.insert(s);
+ }
+ uint64_t num_broken_root_squash_clients() const {
+ return broken_root_squash_clients.size();
+ }
+ auto const& get_broken_root_squash_clients() const {
+ return broken_root_squash_clients;
+ }
+
Session *get_oldest_session(int state) {
auto by_state_entry = by_state.find(state);
if (by_state_entry == by_state.end() || by_state_entry->second->empty())
@@ -849,6 +859,8 @@ private:
bool validate_and_encode_session(MDSRank *mds, Session *session, bufferlist& bl);
void apply_blocklist(const std::set<entity_name_t>& victims);
+
+ std::set<Session*> broken_root_squash_clients;
};
std::ostream& operator<<(std::ostream &out, const Session &s);
diff --git a/src/mds/mdstypes.cc b/src/mds/mdstypes.cc
index 044c33459..114ca137b 100644
--- a/src/mds/mdstypes.cc
+++ b/src/mds/mdstypes.cc
@@ -7,6 +7,10 @@
#include "common/Formatter.h"
#include "common/StackStringStream.h"
+#include <iostream>
+#include <sstream>
+#include <string>
+
const mds_gid_t MDS_GID_NONE = mds_gid_t(0);
using std::list;
@@ -429,7 +433,7 @@ feature_bitset_t::feature_bitset_t(unsigned long value)
}
}
-feature_bitset_t::feature_bitset_t(const vector<size_t>& array)
+void feature_bitset_t::init_array(const vector<size_t>& array)
{
if (!array.empty()) {
size_t n = array.back();
@@ -448,6 +452,26 @@ feature_bitset_t::feature_bitset_t(const vector<size_t>& array)
}
}
+feature_bitset_t::feature_bitset_t(std::string_view str)
+{
+ std::stringstream ss;
+ std::vector<size_t> v;
+ std::string atom;
+
+ ss << str;
+ while (std::getline(ss, atom, ',')) {
+ v.push_back(std::stoul(atom));
+ }
+ std::sort(v.begin(), v.end());
+
+ init_array(v);
+}
+
+feature_bitset_t::feature_bitset_t(const vector<size_t>& array)
+{
+ init_array(array);
+}
+
feature_bitset_t& feature_bitset_t::operator-=(const feature_bitset_t& other)
{
for (size_t i = 0; i < _vec.size(); ++i) {
diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h
index 3381d44c9..8e7b16761 100644
--- a/src/mds/mdstypes.h
+++ b/src/mds/mdstypes.h
@@ -294,6 +294,7 @@ public:
feature_bitset_t(const feature_bitset_t& other) : _vec(other._vec) {}
feature_bitset_t(feature_bitset_t&& other) : _vec(std::move(other._vec)) {}
feature_bitset_t(unsigned long value = 0);
+ feature_bitset_t(std::string_view);
feature_bitset_t(const std::vector<size_t>& array);
feature_bitset_t& operator=(const feature_bitset_t& other) {
_vec = other._vec;
@@ -347,6 +348,8 @@ public:
void dump(ceph::Formatter *f) const;
void print(std::ostream& out) const;
private:
+ void init_array(const std::vector<size_t>& v);
+
std::vector<block_type> _vec;
};
WRITE_CLASS_ENCODER(feature_bitset_t)
diff --git a/src/messages/MMDSBeacon.h b/src/messages/MMDSBeacon.h
index d843b0e76..2323f78d8 100644
--- a/src/messages/MMDSBeacon.h
+++ b/src/messages/MMDSBeacon.h
@@ -46,6 +46,8 @@ enum mds_metric_t {
MDS_HEALTH_CACHE_OVERSIZED,
MDS_HEALTH_SLOW_METADATA_IO,
MDS_HEALTH_CLIENTS_LAGGY,
+ MDS_HEALTH_CLIENTS_LAGGY_MANY,
+ MDS_HEALTH_CLIENTS_BROKEN_ROOTSQUASH,
MDS_HEALTH_DUMMY, // not a real health warning, for testing
};
@@ -65,6 +67,7 @@ inline const char *mds_metric_name(mds_metric_t m)
case MDS_HEALTH_CACHE_OVERSIZED: return "MDS_CACHE_OVERSIZED";
case MDS_HEALTH_SLOW_METADATA_IO: return "MDS_SLOW_METADATA_IO";
case MDS_HEALTH_CLIENTS_LAGGY: return "MDS_CLIENTS_LAGGY";
+ case MDS_HEALTH_CLIENTS_BROKEN_ROOTSQUASH: return "MDS_CLIENTS_BROKEN_ROOTSQUASH";
case MDS_HEALTH_DUMMY: return "MDS_DUMMY";
default:
return "???";
@@ -101,6 +104,8 @@ inline const char *mds_metric_summary(mds_metric_t m)
return "%num% MDSs report slow metadata IOs";
case MDS_HEALTH_CLIENTS_LAGGY:
return "%num% client(s) laggy due to laggy OSDs";
+ case MDS_HEALTH_CLIENTS_BROKEN_ROOTSQUASH:
+ return "%num% MDS report clients with broken root_squash implementation";
default:
return "???";
}
diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc
index 0ac5060f7..88894d73f 100644
--- a/src/mon/MDSMonitor.cc
+++ b/src/mon/MDSMonitor.cc
@@ -275,6 +275,7 @@ void MDSMonitor::encode_pending(MonitorDBStore::TransactionRef t)
}
pending.get_health_checks(&new_checks);
for (auto& p : new_checks.checks) {
+ // TODO: handle "client_count" metadata when summarizing
p.second.summary = std::regex_replace(
p.second.summary,
std::regex("%num%"),
diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc
index 5fb73084d..6468e605c 100644
--- a/src/osd/OSDMap.cc
+++ b/src/osd/OSDMap.cc
@@ -1747,9 +1747,12 @@ uint64_t OSDMap::get_features(int entity_type, uint64_t *pmask) const
}
mask |= CEPH_FEATURES_CRUSH;
- if (!pg_upmap.empty() || !pg_upmap_items.empty() || !pg_upmap_primaries.empty())
+ if (!pg_upmap.empty() || !pg_upmap_items.empty())
features |= CEPH_FEATUREMASK_OSDMAP_PG_UPMAP;
mask |= CEPH_FEATUREMASK_OSDMAP_PG_UPMAP;
+ if (!pg_upmap_primaries.empty())
+ features |= CEPH_FEATUREMASK_SERVER_REEF;
+ mask |= CEPH_FEATUREMASK_SERVER_REEF;
for (auto &pool: pools) {
if (pool.second.has_flag(pg_pool_t::FLAG_HASHPSPOOL)) {
@@ -1821,6 +1824,9 @@ ceph_release_t OSDMap::get_min_compat_client() const
{
uint64_t f = get_features(CEPH_ENTITY_TYPE_CLIENT, nullptr);
+ if (HAVE_FEATURE(f, SERVER_REEF)) { // v18.2.3 (upmap-primary; see #61948)
+ return ceph_release_t::reef;
+ }
if (HAVE_FEATURE(f, OSDMAP_PG_UPMAP) || // v12.0.0-1733-g27d6f43
HAVE_FEATURE(f, CRUSH_CHOOSE_ARGS)) { // v12.0.1-2172-gef1ef28
return ceph_release_t::luminous; // v12.2.0
diff --git a/src/pybind/mgr/k8sevents/module.py b/src/pybind/mgr/k8sevents/module.py
index b34029209..5855ba42e 100644
--- a/src/pybind/mgr/k8sevents/module.py
+++ b/src/pybind/mgr/k8sevents/module.py
@@ -67,7 +67,11 @@ else:
# which causes an exception in the generator. A workaround is discussed for a similar issue
# in https://github.com/kubernetes-client/python/issues/376 which has been used here
# pylint: disable=no-member
- from kubernetes.client.models.v1_event import V1Event
+ try:
+ from kubernetes.client.models.core_v1_event import CoreV1Event as V1Event
+ except ImportError:
+ from kubernetes.client.models.v1_event import V1Event
+
def local_involved_object(self, involved_object):
if involved_object is None:
involved_object = client.V1ObjectReference(api_version="1")
@@ -409,14 +413,14 @@ class KubernetesEvent(object):
event_source = client.V1EventSource(component="ceph-mgr",
host=self.host)
- return client.V1Event(
- involved_object=obj_ref,
- metadata=obj_meta,
- message=self.message,
- count=self.count,
+ return V1Event(
+ involved_object=obj_ref,
+ metadata=obj_meta,
+ message=self.message,
+ count=self.count,
type=self.event_type,
reason=self.event_reason,
- source=event_source,
+ source=event_source,
first_timestamp=self.first_timestamp,
last_timestamp=self.last_timestamp
)
diff --git a/src/pybind/mgr/requirements.txt b/src/pybind/mgr/requirements.txt
index 7daee3323..044674f9b 100644
--- a/src/pybind/mgr/requirements.txt
+++ b/src/pybind/mgr/requirements.txt
@@ -1,5 +1,5 @@
-rrequirements-required.txt
asyncssh==2.9
-kubernetes==11.0.0
+kubernetes
urllib3==1.26.15
pytest==7.4.4