1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "include/compat.h"
5 #include "CrushLocation.h"
6 #include "CrushWrapper.h"
7 #include "common/config.h"
8 #include "include/str_list.h"
9 #include "common/debug.h"
10 #include "include/compat.h"
12 #include <common/SubProcess.h>
16 int CrushLocation::update_from_conf()
18 if (cct
->_conf
->crush_location
.length())
19 return _parse(cct
->_conf
->crush_location
);
23 int CrushLocation::_parse(const std::string
& s
)
25 std::multimap
<std::string
,std::string
> new_crush_location
;
26 std::vector
<std::string
> lvec
;
27 get_str_vec(s
, ";, \t", lvec
);
28 int r
= CrushWrapper::parse_loc_multimap(lvec
, &new_crush_location
);
30 lderr(cct
) << "warning: crush_location '" << cct
->_conf
->crush_location
31 << "' does not parse, keeping original crush_location "
35 std::lock_guard
<std::mutex
> l(lock
);
36 loc
.swap(new_crush_location
);
37 lgeneric_dout(cct
, 10) << "crush_location is " << loc
<< dendl
;
41 int CrushLocation::update_from_hook()
43 if (cct
->_conf
->crush_location_hook
.length() == 0)
46 if (0 != access(cct
->_conf
->crush_location_hook
.c_str(), R_OK
)) {
47 lderr(cct
) << "the user define crush location hook: " << cct
->_conf
->crush_location_hook
48 << " may not exist or can not access it" << dendl
;
53 cct
->_conf
->crush_location_hook
.c_str(),
54 SubProcess::CLOSE
, SubProcess::PIPE
, SubProcess::PIPE
,
55 cct
->_conf
->crush_location_hook_timeout
);
57 "--cluster", cct
->_conf
->cluster
.c_str(),
58 "--id", cct
->_conf
->name
.get_id().c_str(),
59 "--type", cct
->_conf
->name
.get_type_str(),
61 int ret
= hook
.spawn();
63 lderr(cct
) << "error: failed run " << cct
->_conf
->crush_location_hook
<< ": "
64 << hook
.err() << dendl
;
69 ret
= bl
.read_fd(hook
.get_stdout(), 100 * 1024);
71 lderr(cct
) << "error: failed read stdout from "
72 << cct
->_conf
->crush_location_hook
73 << ": " << cpp_strerror(-ret
) << dendl
;
75 err
.read_fd(hook
.get_stderr(), 100 * 1024);
76 lderr(cct
) << "stderr:\n";
82 if (hook
.join() != 0) {
83 lderr(cct
) << "error: failed to join: " << hook
.err() << dendl
;
88 bl
.copy(0, bl
.length(), out
);
89 out
.erase(out
.find_last_not_of(" \n\r\t")+1);
93 int CrushLocation::init_on_startup()
95 if (cct
->_conf
->crush_location
.length()) {
96 return update_from_conf();
98 if (cct
->_conf
->crush_location_hook
.length()) {
99 return update_from_hook();
102 // start with a sane default
103 char hostname
[HOST_NAME_MAX
+ 1];
104 int r
= gethostname(hostname
, sizeof(hostname
)-1);
106 strcpy(hostname
, "unknown_host");
107 // use short hostname
108 for (unsigned i
=0; hostname
[i
]; ++i
) {
109 if (hostname
[i
] == '.') {
114 std::lock_guard
<std::mutex
> l(lock
);
116 loc
.insert(make_pair
<std::string
,std::string
>("host", hostname
));
117 loc
.insert(make_pair
<std::string
,std::string
>("root", "default"));
118 lgeneric_dout(cct
, 10) << "crush_location is (default) " << loc
<< dendl
;