]> git.proxmox.com Git - ceph.git/blame - ceph/src/crush/CrushLocation.cc
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / crush / CrushLocation.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
20effc67 4#include <vector>
f51cf556 5#include <boost/algorithm/string/trim.hpp>
20effc67 6
7c673cae
FG
7#include "CrushLocation.h"
8#include "CrushWrapper.h"
11fdf7f2 9#include "common/ceph_context.h"
7c673cae 10#include "common/config.h"
7c673cae 11#include "common/debug.h"
11fdf7f2 12#include "common/errno.h"
9f95a23c 13#include "include/common_fwd.h"
7c673cae 14#include "include/compat.h"
20effc67 15#include "include/str_list.h"
7c673cae 16
1e59de90 17namespace ceph::crush {
9f95a23c 18
7c673cae
FG
19int CrushLocation::update_from_conf()
20{
21 if (cct->_conf->crush_location.length())
22 return _parse(cct->_conf->crush_location);
23 return 0;
24}
25
26int CrushLocation::_parse(const std::string& s)
27{
28 std::multimap<std::string,std::string> new_crush_location;
29 std::vector<std::string> lvec;
30 get_str_vec(s, ";, \t", lvec);
31 int r = CrushWrapper::parse_loc_multimap(lvec, &new_crush_location);
32 if (r < 0) {
33 lderr(cct) << "warning: crush_location '" << cct->_conf->crush_location
34 << "' does not parse, keeping original crush_location "
35 << loc << dendl;
36 return -EINVAL;
37 }
9f95a23c 38 std::lock_guard l(lock);
7c673cae
FG
39 loc.swap(new_crush_location);
40 lgeneric_dout(cct, 10) << "crush_location is " << loc << dendl;
41 return 0;
42}
43
44int CrushLocation::update_from_hook()
45{
46 if (cct->_conf->crush_location_hook.length() == 0)
47 return 0;
48
49 if (0 != access(cct->_conf->crush_location_hook.c_str(), R_OK)) {
50 lderr(cct) << "the user define crush location hook: " << cct->_conf->crush_location_hook
51 << " may not exist or can not access it" << dendl;
52 return errno;
53 }
54
55 SubProcessTimed hook(
56 cct->_conf->crush_location_hook.c_str(),
57 SubProcess::CLOSE, SubProcess::PIPE, SubProcess::PIPE,
58 cct->_conf->crush_location_hook_timeout);
59 hook.add_cmd_args(
60 "--cluster", cct->_conf->cluster.c_str(),
61 "--id", cct->_conf->name.get_id().c_str(),
62 "--type", cct->_conf->name.get_type_str(),
63 NULL);
64 int ret = hook.spawn();
65 if (ret != 0) {
66 lderr(cct) << "error: failed run " << cct->_conf->crush_location_hook << ": "
67 << hook.err() << dendl;
68 return ret;
69 }
70
9f95a23c 71 ceph::buffer::list bl;
7c673cae
FG
72 ret = bl.read_fd(hook.get_stdout(), 100 * 1024);
73 if (ret < 0) {
74 lderr(cct) << "error: failed read stdout from "
75 << cct->_conf->crush_location_hook
76 << ": " << cpp_strerror(-ret) << dendl;
9f95a23c 77 ceph::buffer::list err;
7c673cae
FG
78 err.read_fd(hook.get_stderr(), 100 * 1024);
79 lderr(cct) << "stderr:\n";
80 err.hexdump(*_dout);
81 *_dout << dendl;
7c673cae
FG
82 }
83
84 if (hook.join() != 0) {
85 lderr(cct) << "error: failed to join: " << hook.err() << dendl;
86 return -EINVAL;
87 }
88
11fdf7f2
TL
89 if (ret < 0)
90 return ret;
91
7c673cae 92 std::string out;
9f95a23c 93 bl.begin().copy(bl.length(), out);
f51cf556 94 boost::algorithm::trim_right_if(out, boost::algorithm::is_any_of(" \n\r\t"));
7c673cae
FG
95 return _parse(out);
96}
97
98int CrushLocation::init_on_startup()
99{
100 if (cct->_conf->crush_location.length()) {
101 return update_from_conf();
102 }
103 if (cct->_conf->crush_location_hook.length()) {
104 return update_from_hook();
105 }
106
107 // start with a sane default
108 char hostname[HOST_NAME_MAX + 1];
92f5a8d4 109 int r = gethostname(hostname, sizeof(hostname));
7c673cae
FG
110 if (r < 0)
111 strcpy(hostname, "unknown_host");
112 // use short hostname
113 for (unsigned i=0; hostname[i]; ++i) {
114 if (hostname[i] == '.') {
115 hostname[i] = '\0';
116 break;
117 }
118 }
9f95a23c 119 std::lock_guard l(lock);
7c673cae 120 loc.clear();
9f95a23c
TL
121 loc.insert(std::make_pair<std::string,std::string>("host", hostname));
122 loc.insert(std::make_pair<std::string,std::string>("root", "default"));
7c673cae
FG
123 return 0;
124}
9f95a23c
TL
125
126std::multimap<std::string,std::string> CrushLocation::get_location() const
127{
128 std::lock_guard l(lock);
129 return loc;
130}
131
132std::ostream& operator<<(std::ostream& os, const CrushLocation& loc)
133{
134 bool first = true;
135 for (auto& [type, pos] : loc.get_location()) {
136 if (first) {
137 first = false;
138 } else {
139 os << ", ";
140 }
141 os << '"' << type << '=' << pos << '"';
142 }
143 return os;
144}
145
146}