]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/util.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2012 Inktank Storage, Inc.
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include <sys/utsname.h>
16 #include <boost/lexical_cast.hpp>
18 #include "include/compat.h"
19 #include "include/util.h"
20 #include "common/debug.h"
21 #include "common/errno.h"
22 #include "common/version.h"
28 #if defined(DARWIN) || defined(__FreeBSD__)
29 #include <sys/param.h>
30 #include <sys/mount.h>
37 int get_fs_stats(ceph_data_stats_t
&stats
, const char *path
)
43 int err
= ::statfs(path
, &stbuf
);
48 stats
.byte_total
= stbuf
.f_blocks
* stbuf
.f_bsize
;
49 stats
.byte_used
= (stbuf
.f_blocks
- stbuf
.f_bfree
) * stbuf
.f_bsize
;
50 stats
.byte_avail
= stbuf
.f_bavail
* stbuf
.f_bsize
;
51 stats
.avail_percent
= (((float)stats
.byte_avail
/stats
.byte_total
)*100);
55 static char* value_sanitize(char *value
)
57 while (isspace(*value
) || *value
== '"')
60 char* end
= value
+ strlen(value
) - 1;
61 while (end
> value
&& (isspace(*end
) || *end
== '"'))
69 static bool value_set(char *buf
, const char *prefix
,
70 map
<string
, string
> *pm
, const char *key
)
72 if (strncmp(buf
, prefix
, strlen(prefix
))) {
76 (*pm
)[key
] = value_sanitize(buf
+ strlen(prefix
));
80 static void file_values_parse(const map
<string
, string
>& kvm
, FILE *fp
, map
<string
, string
> *m
, CephContext
*cct
) {
82 while (fgets(buf
, sizeof(buf
) - 1, fp
) != NULL
) {
83 for (auto& kv
: kvm
) {
84 if (value_set(buf
, kv
.second
.c_str(), m
, kv
.first
.c_str()))
90 static bool os_release_parse(map
<string
, string
> *m
, CephContext
*cct
)
92 static const map
<string
, string
> kvm
= {
94 { "distro_description", "PRETTY_NAME=" },
95 { "distro_version", "VERSION_ID=" }
98 FILE *fp
= fopen("/etc/os-release", "r");
101 lderr(cct
) << "os_release_parse - failed to open /etc/os-release: " << cpp_strerror(ret
) << dendl
;
105 file_values_parse(kvm
, fp
, m
, cct
);
112 static void distro_detect(map
<string
, string
> *m
, CephContext
*cct
)
114 if (!os_release_parse(m
, cct
)) {
115 lderr(cct
) << "distro_detect - /etc/os-release is required" << dendl
;
118 for (const char* rk
: {"distro", "distro_description"}) {
119 if (m
->find(rk
) == m
->end())
120 lderr(cct
) << "distro_detect - can't detect " << rk
<< dendl
;
124 void collect_sys_info(map
<string
, string
> *m
, CephContext
*cct
)
127 (*m
)["ceph_version"] = pretty_version_to_str();
133 (*m
)["os"] = u
.sysname
;
134 (*m
)["kernel_version"] = u
.release
;
135 (*m
)["kernel_description"] = u
.version
;
136 (*m
)["hostname"] = u
.nodename
;
137 (*m
)["arch"] = u
.machine
;
141 FILE *f
= fopen(PROCPREFIX
"/proc/meminfo", "r");
145 char *line
= fgets(buf
, sizeof(buf
), f
);
150 int r
= sscanf(line
, "%s %lld", key
, &value
);
152 if (strcmp(key
, "MemTotal:") == 0)
153 (*m
)["mem_total_kb"] = boost::lexical_cast
<string
>(value
);
154 else if (strcmp(key
, "SwapTotal:") == 0)
155 (*m
)["mem_swap_kb"] = boost::lexical_cast
<string
>(value
);
162 f
= fopen(PROCPREFIX
"/proc/cpuinfo", "r");
166 char *line
= fgets(buf
, sizeof(buf
), f
);
169 if (strncmp(line
, "model name", 10) == 0) {
170 char *c
= strchr(buf
, ':');
186 distro_detect(m
, cct
);
189 void dump_services(Formatter
* f
, const map
<string
, list
<int> >& services
, const char* type
)
193 f
->open_object_section(type
);
194 for (map
<string
, list
<int> >::const_iterator host
= services
.begin();
195 host
!= services
.end(); ++host
) {
196 f
->open_array_section(host
->first
.c_str());
197 const list
<int>& hosted
= host
->second
;
198 for (list
<int>::const_iterator s
= hosted
.begin();
199 s
!= hosted
.end(); ++s
) {
200 f
->dump_int(type
, *s
);
208 // If non-printable characters found then convert bufferlist to
209 // base64 encoded string indicating whether it did.
210 string
cleanbin(bufferlist
&bl
, bool &base64
)
212 bufferlist::iterator it
;
213 for (it
= bl
.begin(); it
!= bl
.end(); ++it
) {
217 if (it
== bl
.end()) {
219 string
result(bl
.c_str(), bl
.length());
224 bl
.encode_base64(b64
);
225 string
encoded(b64
.c_str(), b64
.length());
230 // If non-printable characters found then convert to "Base64:" followed by
232 string
cleanbin(string
&str
)
237 string result
= cleanbin(bl
, base64
);
239 result
= "Base64:" + result
;
243 std::string
bytes2str(uint64_t count
) {
244 static char s
[][2] = {"\0", "k", "M", "G", "T", "P", "E", "\0"};
246 while (count
>= 1024 && *s
[i
+1]) {
251 snprintf(str
, sizeof str
, "%" PRIu64
"%sB", count
, s
[i
]);
252 return std::string(str
);