auto now = ceph_clock_now();
daemon_state.with_devices([&tbl, now](const DeviceState& dev) {
string h;
- for (auto& i : dev.devnames) {
+ for (auto& i : dev.attachments) {
if (h.size()) {
h += " ";
}
- h += i.first + ":" + i.second;
+ h += std::get<0>(i) + ":" + std::get<1>(i);
}
string d;
for (auto& i : dev.daemons) {
daemon_state.with_device(
i.first, [&tbl, now] (const DeviceState& dev) {
string h;
- for (auto& i : dev.devnames) {
+ for (auto& i : dev.attachments) {
if (h.size()) {
h += " ";
}
- h += i.first + ":" + i.second;
+ h += std::get<0>(i) + ":" + std::get<1>(i);
}
tbl << dev.devid
<< h
daemon_state.with_device(
devid, [&tbl, &host, now] (const DeviceState& dev) {
string n;
- for (auto& j : dev.devnames) {
- if (j.first == host) {
+ for (auto& j : dev.attachments) {
+ if (std::get<0>(j) == host) {
if (n.size()) {
n += " ";
}
- n += j.second;
+ n += std::get<1>(j);
}
}
string d;
{
f->dump_string("devid", devid);
f->open_array_section("location");
- for (auto& i : devnames) {
+ for (auto& i : attachments) {
f->open_object_section("attachment");
- f->dump_string("host", i.first);
- f->dump_string("dev", i.second);
+ f->dump_string("host", std::get<0>(i));
+ f->dump_string("dev", std::get<1>(i));
+ f->dump_string("path", std::get<2>(i));
f->close_section();
}
f->close_section();
void DeviceState::print(ostream& out) const
{
out << "device " << devid << "\n";
- for (auto& i : devnames) {
- out << "attachment " << i.first << ":" << i.second << "\n";
+ for (auto& i : attachments) {
+ out << "attachment " << std::get<0>(i) << " " << std::get<1>(i) << " "
+ << std::get<2>(i) << "\n";
+ out << "\n";
}
std::copy(std::begin(daemons), std::end(daemons),
std::experimental::make_ostream_joiner(out, ","));
for (auto& i : dm->devices) {
auto d = _get_or_create_device(i.first);
d->daemons.insert(dm->key);
- d->devnames.insert(make_pair(dm->hostname, i.second));
+ auto p = dm->devices_bypath.find(i.first);
+ if (p != dm->devices_bypath.end()) {
+ d->attachments.insert(std::make_tuple(dm->hostname, i.second, p->second));
+ } else {
+ d->attachments.insert(std::make_tuple(dm->hostname, i.second,
+ std::string()));
+ }
}
}
auto d = _get_or_create_device(i.first);
ceph_assert(d->daemons.count(dmk));
d->daemons.erase(dmk);
- d->devnames.erase(make_pair(dm->hostname, i.second));
+ auto p = dm->devices_bypath.find(i.first);
+ if (p != dm->devices_bypath.end()) {
+ d->attachments.erase(make_tuple(dm->hostname, i.second, p->second));
+ } else {
+ d->attachments.erase(make_tuple(dm->hostname, i.second, std::string()));
+ }
if (d->empty()) {
_erase_device(d);
}
/// device ids -> devname, derived from metadata[device_ids]
std::map<std::string,std::string> devices;
+ /// device ids -> by-path, derived from metadata[device_ids]
+ std::map<std::string,std::string> devices_bypath;
+
// TODO: this can be generalized to other daemons
std::vector<DaemonHealthMetric> daemon_health_metrics;
void set_metadata(const std::map<std::string,std::string>& m) {
devices.clear();
+ devices_bypath.clear();
metadata = m;
auto p = m.find("device_ids");
if (p != m.end()) {
- map<std::string,std::string> devs;
+ map<std::string,std::string> devs, paths; // devname -> id or path
get_str_map(p->second, &devs, ",; ");
+ auto q = m.find("device_paths");
+ if (q != m.end()) {
+ get_str_map(q->second, &paths, ",; ");
+ }
for (auto& i : devs) {
if (i.second.size()) { // skip blank ids
- devices[i.second] = i.first;
+ devices[i.second] = i.first; // id -> devname
+ auto j = paths.find(i.first);
+ if (j != paths.end()) {
+ devices_bypath[i.second] = j->second; // id -> path
+ }
}
}
}
struct DeviceState : public RefCountedObject
{
std::string devid;
- std::set<pair<std::string,std::string>> devnames; ///< (server,devname)
+ /// (server,devname,path)
+ std::set<std::tuple<std::string,std::string,std::string>> attachments;
std::set<DaemonKey> daemons;
std::map<string,string> metadata; ///< persistent metadata