| @@ -1,218 +1,217 @@ | | | @@ -1,218 +1,217 @@ |
1 | $NetBSD: patch-src_mongo_util_processinfo__netbsd.cpp,v 1.1 2016/02/12 03:37:24 ryoon Exp $ | | 1 | $NetBSD: patch-src_mongo_util_processinfo__netbsd.cpp,v 1.2 2017/06/24 04:24:56 kamil Exp $ |
2 | | | 2 | |
3 | --- src/mongo/util/processinfo_netbsd.cpp.orig 2016-02-11 22:14:23.486964953 +0000 | | 3 | --- src/mongo/util/processinfo_netbsd.cpp.orig 2017-06-24 01:47:17.271883765 +0000 |
4 | +++ src/mongo/util/processinfo_netbsd.cpp | | 4 | +++ src/mongo/util/processinfo_netbsd.cpp |
5 | @@ -0,0 +1,213 @@ | | 5 | @@ -0,0 +1,212 @@ |
6 | +/* Copyright 2012 10gen Inc. | | 6 | +/* Copyright 2012 10gen Inc. |
7 | + * | | 7 | + * |
8 | + * This program is free software: you can redistribute it and/or modify | | 8 | + * This program is free software: you can redistribute it and/or modify |
9 | + * it under the terms of the GNU Affero General Public License, version 3, | | 9 | + * it under the terms of the GNU Affero General Public License, version 3, |
10 | + * as published by the Free Software Foundation. | | 10 | + * as published by the Free Software Foundation. |
11 | + * | | 11 | + * |
12 | + * This program is distributed in the hope that it will be useful, | | 12 | + * This program is distributed in the hope that it will be useful, |
13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | | 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | + * GNU Affero General Public License for more details. | | 15 | + * GNU Affero General Public License for more details. |
16 | + * | | 16 | + * |
17 | + * You should have received a copy of the GNU Affero General Public License | | 17 | + * You should have received a copy of the GNU Affero General Public License |
18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | | 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | + * | | 19 | + * |
20 | + * As a special exception, the copyright holders give permission to link the | | 20 | + * As a special exception, the copyright holders give permission to link the |
21 | + * code of portions of this program with the OpenSSL library under certain | | 21 | + * code of portions of this program with the OpenSSL library under certain |
22 | + * conditions as described in each individual source file and distribute | | 22 | + * conditions as described in each individual source file and distribute |
23 | + * linked combinations including the program with the OpenSSL library. You | | 23 | + * linked combinations including the program with the OpenSSL library. You |
24 | + * must comply with the GNU Affero General Public License in all respects | | 24 | + * must comply with the GNU Affero General Public License in all respects |
25 | + * for all of the code used other than as permitted herein. If you modify | | 25 | + * for all of the code used other than as permitted herein. If you modify |
26 | + * file(s) with this exception, you may extend this exception to your | | 26 | + * file(s) with this exception, you may extend this exception to your |
27 | + * version of the file(s), but you are not obligated to do so. If you do not | | 27 | + * version of the file(s), but you are not obligated to do so. If you do not |
28 | + * wish to do so, delete this exception statement from your version. If you | | 28 | + * wish to do so, delete this exception statement from your version. If you |
29 | + * delete this exception statement from all source files in the program, | | 29 | + * delete this exception statement from all source files in the program, |
30 | + * then also delete it in the license file. | | 30 | + * then also delete it in the license file. |
31 | + */ | | 31 | + */ |
32 | + | | 32 | + |
33 | +#if defined(__NetBSD__) | | 33 | +#if defined(__NetBSD__) |
34 | +#define _KMEMUSER | | 34 | +#define _KMEMUSER |
35 | +#endif | | 35 | +#endif |
36 | + | | 36 | + |
37 | +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kControl | | 37 | +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kControl |
38 | + | | 38 | + |
39 | +#include <cstdlib> | | 39 | +#include <cstdlib> |
40 | +#include <string> | | 40 | +#include <string> |
41 | + | | 41 | + |
42 | +#include <kvm.h> | | 42 | +#include <kvm.h> |
43 | +#include <sys/file.h> | | 43 | +#include <sys/file.h> |
44 | +#include <sys/mman.h> | | 44 | +#include <sys/mman.h> |
45 | +#include <sys/param.h> | | 45 | +#include <sys/param.h> |
46 | +#include <sys/sysctl.h> | | 46 | +#include <sys/sysctl.h> |
47 | +#include <sys/types.h> | | 47 | +#include <sys/types.h> |
48 | +#include <sys/user.h> | | | |
49 | +#include <sys/vmmeter.h> | | 48 | +#include <sys/vmmeter.h> |
50 | +#include <unistd.h> | | 49 | +#include <unistd.h> |
51 | + | | 50 | + |
52 | +#include "mongo/util/scopeguard.h" | | 51 | +#include "mongo/util/scopeguard.h" |
53 | +#include "mongo/util/log.h" | | 52 | +#include "mongo/util/log.h" |
54 | +#include "processinfo.h" | | 53 | +#include "processinfo.h" |
55 | + | | 54 | + |
56 | +using namespace std; | | 55 | +using namespace std; |
57 | + | | 56 | + |
58 | +namespace mongo { | | 57 | +namespace mongo { |
59 | + | | 58 | + |
60 | +ProcessInfo::ProcessInfo(ProcessId pid) : _pid(pid) {} | | 59 | +ProcessInfo::ProcessInfo(ProcessId pid) : _pid(pid) {} |
61 | + | | 60 | + |
62 | +ProcessInfo::~ProcessInfo() {} | | 61 | +ProcessInfo::~ProcessInfo() {} |
63 | + | | 62 | + |
64 | +/** | | 63 | +/** |
65 | + * Get a sysctl string value by name. Use string specialization by default. | | 64 | + * Get a sysctl string value by name. Use string specialization by default. |
66 | + */ | | 65 | + */ |
67 | +template <typename T> | | 66 | +template <typename T> |
68 | +int getSysctlByIDWithDefault(const int* sysctlID, | | 67 | +int getSysctlByIDWithDefault(const int* sysctlID, |
69 | + const int idLen, | | 68 | + const int idLen, |
70 | + const T& defaultValue, | | 69 | + const T& defaultValue, |
71 | + T* result); | | 70 | + T* result); |
72 | + | | 71 | + |
73 | +template <> | | 72 | +template <> |
74 | +int getSysctlByIDWithDefault<uintptr_t>(const int* sysctlID, | | 73 | +int getSysctlByIDWithDefault<uintptr_t>(const int* sysctlID, |
75 | + const int idLen, | | 74 | + const int idLen, |
76 | + const uintptr_t& defaultValue, | | 75 | + const uintptr_t& defaultValue, |
77 | + uintptr_t* result) { | | 76 | + uintptr_t* result) { |
78 | + uintptr_t value = 0; | | 77 | + uintptr_t value = 0; |
79 | + size_t len = sizeof(value); | | 78 | + size_t len = sizeof(value); |
80 | + if (sysctl(sysctlID, idLen, &value, &len, NULL, 0) == -1) { | | 79 | + if (sysctl(sysctlID, idLen, &value, &len, NULL, 0) == -1) { |
81 | + *result = defaultValue; | | 80 | + *result = defaultValue; |
82 | + return errno; | | 81 | + return errno; |
83 | + } | | 82 | + } |
84 | + if (len > sizeof(value)) { | | 83 | + if (len > sizeof(value)) { |
85 | + *result = defaultValue; | | 84 | + *result = defaultValue; |
86 | + return EINVAL; | | 85 | + return EINVAL; |
87 | + } | | 86 | + } |
88 | + | | 87 | + |
89 | + *result = value; | | 88 | + *result = value; |
90 | + return 0; | | 89 | + return 0; |
91 | +} | | 90 | +} |
92 | + | | 91 | + |
93 | +template <> | | 92 | +template <> |
94 | +int getSysctlByIDWithDefault<string>(const int* sysctlID, | | 93 | +int getSysctlByIDWithDefault<string>(const int* sysctlID, |
95 | + const int idLen, | | 94 | + const int idLen, |
96 | + const string& defaultValue, | | 95 | + const string& defaultValue, |
97 | + string* result) { | | 96 | + string* result) { |
98 | + char value[256] = {0}; | | 97 | + char value[256] = {0}; |
99 | + size_t len = sizeof(value); | | 98 | + size_t len = sizeof(value); |
100 | + if (sysctl(sysctlID, idLen, &value, &len, NULL, 0) == -1) { | | 99 | + if (sysctl(sysctlID, idLen, &value, &len, NULL, 0) == -1) { |
101 | + *result = defaultValue; | | 100 | + *result = defaultValue; |
102 | + return errno; | | 101 | + return errno; |
103 | + } | | 102 | + } |
104 | + *result = value; | | 103 | + *result = value; |
105 | + return 0; | | 104 | + return 0; |
106 | +} | | 105 | +} |
107 | + | | 106 | + |
108 | +bool ProcessInfo::checkNumaEnabled() { | | 107 | +bool ProcessInfo::checkNumaEnabled() { |
109 | + return false; | | 108 | + return false; |
110 | +} | | 109 | +} |
111 | + | | 110 | + |
112 | +int ProcessInfo::getVirtualMemorySize() { | | 111 | +int ProcessInfo::getVirtualMemorySize() { |
113 | + kvm_t* kd = NULL; | | 112 | + kvm_t* kd = NULL; |
114 | + int cnt = 0; | | 113 | + int cnt = 0; |
115 | + char err[_POSIX2_LINE_MAX] = {0}; | | 114 | + char err[_POSIX2_LINE_MAX] = {0}; |
116 | + if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, err)) == NULL) { | | 115 | + if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, err)) == NULL) { |
117 | + log() << "Unable to get virt mem size: " << err << endl; | | 116 | + log() << "Unable to get virt mem size: " << err << endl; |
118 | + return -1; | | 117 | + return -1; |
119 | + } | | 118 | + } |
120 | + | | 119 | + |
121 | + kinfo_proc2* task = kvm_getproc2(kd, KERN_PROC_PID, _pid.toNative(), sizeof(kinfo_proc2), &cnt); | | 120 | + kinfo_proc2* task = kvm_getproc2(kd, KERN_PROC_PID, _pid.toNative(), sizeof(kinfo_proc2), &cnt); |
122 | + kvm_close(kd); | | 121 | + kvm_close(kd); |
123 | + return ((task->p_vm_dsize + task->p_vm_ssize + task->p_vm_tsize) * sysconf(_SC_PAGESIZE)) / | | 122 | + return ((task->p_vm_dsize + task->p_vm_ssize + task->p_vm_tsize) * sysconf(_SC_PAGESIZE)) / |
124 | + 1048576; | | 123 | + 1048576; |
125 | +} | | 124 | +} |
126 | + | | 125 | + |
127 | +int ProcessInfo::getResidentSize() { | | 126 | +int ProcessInfo::getResidentSize() { |
128 | + kvm_t* kd = NULL; | | 127 | + kvm_t* kd = NULL; |
129 | + int cnt = 0; | | 128 | + int cnt = 0; |
130 | + char err[_POSIX2_LINE_MAX] = {0}; | | 129 | + char err[_POSIX2_LINE_MAX] = {0}; |
131 | + if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, err)) == NULL) { | | 130 | + if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, err)) == NULL) { |
132 | + log() << "Unable to get res mem size: " << err << endl; | | 131 | + log() << "Unable to get res mem size: " << err << endl; |
133 | + return -1; | | 132 | + return -1; |
134 | + } | | 133 | + } |
135 | + kinfo_proc2* task = kvm_getproc2(kd, KERN_PROC_PID, _pid.toNative(), sizeof(kinfo_proc2), &cnt); | | 134 | + kinfo_proc2* task = kvm_getproc2(kd, KERN_PROC_PID, _pid.toNative(), sizeof(kinfo_proc2), &cnt); |
136 | + kvm_close(kd); | | 135 | + kvm_close(kd); |
137 | + return (task->p_vm_rssize * sysconf(_SC_PAGESIZE)) / 1048576; // convert from pages to MB | | 136 | + return (task->p_vm_rssize * sysconf(_SC_PAGESIZE)) / 1048576; // convert from pages to MB |
138 | +} | | 137 | +} |
139 | + | | 138 | + |
140 | +double ProcessInfo::getSystemMemoryPressurePercentage() { | | 139 | +double ProcessInfo::getSystemMemoryPressurePercentage() { |
141 | + return 0.0; | | 140 | + return 0.0; |
142 | +} | | 141 | +} |
143 | + | | 142 | + |
144 | +void ProcessInfo::SystemInfo::collectSystemInfo() { | | 143 | +void ProcessInfo::SystemInfo::collectSystemInfo() { |
145 | + osType = "BSD"; | | 144 | + osType = "BSD"; |
146 | + osName = "NetBSD"; | | 145 | + osName = "NetBSD"; |
147 | + int mib[2]; | | 146 | + int mib[2]; |
148 | + | | 147 | + |
149 | + mib[0] = CTL_KERN; | | 148 | + mib[0] = CTL_KERN; |
150 | + mib[1] = KERN_VERSION; | | 149 | + mib[1] = KERN_VERSION; |
151 | + int status = getSysctlByIDWithDefault(mib, 2, string("unknown"), &osVersion); | | 150 | + int status = getSysctlByIDWithDefault(mib, 2, string("unknown"), &osVersion); |
152 | + if (status != 0) | | 151 | + if (status != 0) |
153 | + log() << "Unable to collect OS Version. (errno: " << status << " msg: " << strerror(status) | | 152 | + log() << "Unable to collect OS Version. (errno: " << status << " msg: " << strerror(status) |
154 | + << ")" << endl; | | 153 | + << ")" << endl; |
155 | + | | 154 | + |
156 | + mib[0] = CTL_HW; | | 155 | + mib[0] = CTL_HW; |
157 | + mib[1] = HW_MACHINE; | | 156 | + mib[1] = HW_MACHINE; |
158 | + status = getSysctlByIDWithDefault(mib, 2, string("unknown"), &cpuArch); | | 157 | + status = getSysctlByIDWithDefault(mib, 2, string("unknown"), &cpuArch); |
159 | + if (status != 0) | | 158 | + if (status != 0) |
160 | + log() << "Unable to collect Machine Architecture. (errno: " << status | | 159 | + log() << "Unable to collect Machine Architecture. (errno: " << status |
161 | + << " msg: " << strerror(status) << ")" << endl; | | 160 | + << " msg: " << strerror(status) << ")" << endl; |
162 | + addrSize = cpuArch.find("64") != std::string::npos ? 64 : 32; | | 161 | + addrSize = cpuArch.find("64") != std::string::npos ? 64 : 32; |
163 | + | | 162 | + |
164 | + uintptr_t numBuffer; | | 163 | + uintptr_t numBuffer; |
165 | + uintptr_t defaultNum = 1; | | 164 | + uintptr_t defaultNum = 1; |
166 | + mib[0] = CTL_HW; | | 165 | + mib[0] = CTL_HW; |
167 | + mib[1] = HW_PHYSMEM; | | 166 | + mib[1] = HW_PHYSMEM; |
168 | + status = getSysctlByIDWithDefault(mib, 2, defaultNum, &numBuffer); | | 167 | + status = getSysctlByIDWithDefault(mib, 2, defaultNum, &numBuffer); |
169 | + memSize = numBuffer; | | 168 | + memSize = numBuffer; |
170 | + if (status != 0) | | 169 | + if (status != 0) |
171 | + log() << "Unable to collect Physical Memory. (errno: " << status | | 170 | + log() << "Unable to collect Physical Memory. (errno: " << status |
172 | + << " msg: " << strerror(status) << ")" << endl; | | 171 | + << " msg: " << strerror(status) << ")" << endl; |
173 | + | | 172 | + |
174 | + mib[0] = CTL_HW; | | 173 | + mib[0] = CTL_HW; |
175 | + mib[1] = HW_NCPU; | | 174 | + mib[1] = HW_NCPU; |
176 | + status = getSysctlByIDWithDefault(mib, 2, defaultNum, &numBuffer); | | 175 | + status = getSysctlByIDWithDefault(mib, 2, defaultNum, &numBuffer); |
177 | + numCores = numBuffer; | | 176 | + numCores = numBuffer; |
178 | + if (status != 0) | | 177 | + if (status != 0) |
179 | + log() << "Unable to collect Number of CPUs. (errno: " << status | | 178 | + log() << "Unable to collect Number of CPUs. (errno: " << status |
180 | + << " msg: " << strerror(status) << ")" << endl; | | 179 | + << " msg: " << strerror(status) << ")" << endl; |
181 | + | | 180 | + |
182 | + pageSize = static_cast<unsigned long long>(sysconf(_SC_PAGESIZE)); | | 181 | + pageSize = static_cast<unsigned long long>(sysconf(_SC_PAGESIZE)); |
183 | + | | 182 | + |
184 | + hasNuma = checkNumaEnabled(); | | 183 | + hasNuma = checkNumaEnabled(); |
185 | +} | | 184 | +} |
186 | + | | 185 | + |
187 | +void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {} | | 186 | +void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {} |
188 | + | | 187 | + |
189 | +bool ProcessInfo::supported() { | | 188 | +bool ProcessInfo::supported() { |
190 | + return true; | | 189 | + return true; |
191 | +} | | 190 | +} |
192 | + | | 191 | + |
193 | +bool ProcessInfo::blockCheckSupported() { | | 192 | +bool ProcessInfo::blockCheckSupported() { |
194 | + return true; | | 193 | + return true; |
195 | +} | | 194 | +} |
196 | + | | 195 | + |
197 | +bool ProcessInfo::blockInMemory(const void* start) { | | 196 | +bool ProcessInfo::blockInMemory(const void* start) { |
198 | + char x = 0; | | 197 | + char x = 0; |
199 | + if (mincore((void*)alignToStartOfPage(start), getPageSize(), &x)) { | | 198 | + if (mincore((void*)alignToStartOfPage(start), getPageSize(), &x)) { |
200 | + log() << "mincore failed: " << errnoWithDescription() << endl; | | 199 | + log() << "mincore failed: " << errnoWithDescription() << endl; |
201 | + return 1; | | 200 | + return 1; |
202 | + } | | 201 | + } |
203 | + return x & 0x1; | | 202 | + return x & 0x1; |
204 | +} | | 203 | +} |
205 | + | | 204 | + |
206 | +bool ProcessInfo::pagesInMemory(const void* start, size_t numPages, vector<char>* out) { | | 205 | +bool ProcessInfo::pagesInMemory(const void* start, size_t numPages, vector<char>* out) { |
207 | + out->resize(numPages); | | 206 | + out->resize(numPages); |
208 | + // int mincore(const void *addr, size_t len, char *vec); | | 207 | + // int mincore(const void *addr, size_t len, char *vec); |
209 | + if (mincore((void*)alignToStartOfPage(start), numPages * getPageSize(), &(out->front()))) { | | 208 | + if (mincore((void*)alignToStartOfPage(start), numPages * getPageSize(), &(out->front()))) { |
210 | + log() << "mincore failed: " << errnoWithDescription() << endl; | | 209 | + log() << "mincore failed: " << errnoWithDescription() << endl; |
211 | + return false; | | 210 | + return false; |
212 | + } | | 211 | + } |
213 | + for (size_t i = 0; i < numPages; ++i) { | | 212 | + for (size_t i = 0; i < numPages; ++i) { |
214 | + (*out)[i] = 0x1; | | 213 | + (*out)[i] = 0x1; |
215 | + } | | 214 | + } |
216 | + return true; | | 215 | + return true; |
217 | +} | | 216 | +} |
218 | +} | | 217 | +} |