source: vendor/current/source3/utils/status_profile.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 9.4 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * status reporting
4 * Copyright (C) Andrew Tridgell 1994-1998
5 * Copyright (C) James Peach 2005-2006
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "includes.h"
22#include "smbprofile.h"
23#include "status_profile.h"
24
25static void profile_separator(const char * title)
26{
27 char line[79 + 1];
28 char * end;
29
30 snprintf(line, sizeof(line), "**** %s ", title);
31
32 for (end = line + strlen(line); end < &line[sizeof(line) -1]; ++end) {
33 *end = '*';
34 }
35
36 line[sizeof(line) - 1] = '\0';
37 d_printf("%s\n", line);
38}
39
40/*******************************************************************
41 dump the elements of the profile structure
42 ******************************************************************/
43bool status_profile_dump(bool verbose)
44{
45 struct profile_stats stats = {};
46
47 if (!profile_setup(NULL, True)) {
48 fprintf(stderr,"Failed to initialise profile memory\n");
49 return False;
50 }
51
52 smbprofile_collect(&stats);
53
54#define __PRINT_FIELD_LINE(name, _stats, field) do { \
55 d_printf("%-59s%20ju\n", \
56 name "_" #field ":", \
57 (uintmax_t)stats.values._stats.field); \
58} while(0);
59#define SMBPROFILE_STATS_START
60#define SMBPROFILE_STATS_SECTION_START(name, display) profile_separator(#display);
61#define SMBPROFILE_STATS_COUNT(name) do { \
62 __PRINT_FIELD_LINE(#name, name##_stats, count); \
63} while(0);
64#define SMBPROFILE_STATS_TIME(name) do { \
65 __PRINT_FIELD_LINE(#name, name##_stats, time); \
66} while(0);
67#define SMBPROFILE_STATS_BASIC(name) do { \
68 __PRINT_FIELD_LINE(#name, name##_stats, count); \
69 __PRINT_FIELD_LINE(#name, name##_stats, time); \
70} while(0);
71#define SMBPROFILE_STATS_BYTES(name) do { \
72 __PRINT_FIELD_LINE(#name, name##_stats, count); \
73 __PRINT_FIELD_LINE(#name, name##_stats, time); \
74 __PRINT_FIELD_LINE(#name, name##_stats, idle); \
75 __PRINT_FIELD_LINE(#name, name##_stats, bytes); \
76} while(0);
77#define SMBPROFILE_STATS_IOBYTES(name) do { \
78 __PRINT_FIELD_LINE(#name, name##_stats, count); \
79 __PRINT_FIELD_LINE(#name, name##_stats, time); \
80 __PRINT_FIELD_LINE(#name, name##_stats, idle); \
81 __PRINT_FIELD_LINE(#name, name##_stats, inbytes); \
82 __PRINT_FIELD_LINE(#name, name##_stats, outbytes); \
83} while(0);
84#define SMBPROFILE_STATS_SECTION_END
85#define SMBPROFILE_STATS_END
86 SMBPROFILE_STATS_ALL_SECTIONS
87#undef __PRINT_FIELD_LINE
88#undef SMBPROFILE_STATS_START
89#undef SMBPROFILE_STATS_SECTION_START
90#undef SMBPROFILE_STATS_COUNT
91#undef SMBPROFILE_STATS_TIME
92#undef SMBPROFILE_STATS_BASIC
93#undef SMBPROFILE_STATS_BYTES
94#undef SMBPROFILE_STATS_IOBYTES
95#undef SMBPROFILE_STATS_SECTION_END
96#undef SMBPROFILE_STATS_END
97
98 return True;
99}
100
101/* Convert microseconds to milliseconds. */
102#define usec_to_msec(s) ((s) / 1000)
103/* Convert microseconds to seconds. */
104#define usec_to_sec(s) ((s) / 1000000)
105/* One second in microseconds. */
106#define one_second_usec (1000000)
107
108#define sample_interval_usec one_second_usec
109
110#define percent_time(used, period) ((double)(used) / (double)(period) * 100.0 )
111
112static uint64_t print_count_count_samples(
113 char *buf, const size_t buflen,
114 const char *name,
115 const struct smbprofile_stats_count * const current,
116 const struct smbprofile_stats_count * const last,
117 uint64_t delta_usec)
118{
119 uint64_t step = current->count - last->count;
120 uint64_t count = 0;
121
122 if (step != 0) {
123 uint64_t delta_sec = usec_to_sec(delta_usec);
124
125 count++;
126
127 if (buf[0] == '\0') {
128 snprintf(buf, buflen,
129 "%s %ju/sec",
130 name, (uintmax_t)(step / delta_sec));
131 } else {
132 printf("%-40s %s %ju/sec\n",
133 buf, name, (uintmax_t)(step / delta_sec));
134 buf[0] = '\0';
135 }
136 }
137
138 return count;
139}
140
141static uint64_t print_basic_count_samples(
142 char *buf, const size_t buflen,
143 const char *name,
144 const struct smbprofile_stats_basic * const current,
145 const struct smbprofile_stats_basic * const last,
146 uint64_t delta_usec)
147{
148 uint64_t step = current->count - last->count;
149 uint64_t spent = current->time - last->time;
150 uint64_t count = 0;
151
152 if (step != 0) {
153 uint64_t delta_sec = usec_to_sec(delta_usec);
154
155 count++;
156
157 if (buf[0] == '\0') {
158 snprintf(buf, buflen,
159 "%s %ju/sec (%.2f%%)",
160 name, (uintmax_t)(step / delta_sec),
161 percent_time(spent, delta_usec));
162 } else {
163 printf("%-40s %s %ju/sec (%.2f%%)\n",
164 buf, name, (uintmax_t)(step / delta_sec),
165 percent_time(spent, delta_usec));
166 buf[0] = '\0';
167 }
168 }
169
170 return count;
171}
172
173static uint64_t print_bytes_count_samples(
174 char *buf, const size_t buflen,
175 const char *name,
176 const struct smbprofile_stats_bytes * const current,
177 const struct smbprofile_stats_bytes * const last,
178 uint64_t delta_usec)
179{
180 uint64_t step = current->count - last->count;
181 uint64_t spent = current->time - last->time;
182 uint64_t count = 0;
183
184 if (step != 0) {
185 uint64_t delta_sec = usec_to_sec(delta_usec);
186
187 count++;
188
189 if (buf[0] == '\0') {
190 snprintf(buf, buflen,
191 "%s %ju/sec (%.2f%%)",
192 name, (uintmax_t)(step / delta_sec),
193 percent_time(spent, delta_usec));
194 } else {
195 printf("%-40s %s %ju/sec (%.2f%%)\n",
196 buf, name, (uintmax_t)(step / delta_sec),
197 percent_time(spent, delta_usec));
198 buf[0] = '\0';
199 }
200 }
201
202 return count;
203}
204
205static uint64_t print_iobytes_count_samples(
206 char *buf, const size_t buflen,
207 const char *name,
208 const struct smbprofile_stats_iobytes * const current,
209 const struct smbprofile_stats_iobytes * const last,
210 uint64_t delta_usec)
211{
212 uint64_t step = current->count - last->count;
213 uint64_t spent = current->time - last->time;
214 uint64_t count = 0;
215
216 if (step != 0) {
217 uint64_t delta_sec = usec_to_sec(delta_usec);
218
219 count++;
220
221 if (buf[0] == '\0') {
222 snprintf(buf, buflen,
223 "%s %ju/sec (%.2f%%)",
224 name, (uintmax_t)(step / delta_sec),
225 percent_time(spent, delta_usec));
226 } else {
227 printf("%-40s %s %ju/sec (%.2f%%)\n",
228 buf, name, (uintmax_t)(step / delta_sec),
229 percent_time(spent, delta_usec));
230 buf[0] = '\0';
231 }
232 }
233
234 return count;
235}
236
237static uint64_t print_count_samples(
238 const struct profile_stats * const current,
239 const struct profile_stats * const last,
240 uint64_t delta_usec)
241{
242 uint64_t count = 0;
243 char buf[40] = { '\0', };
244
245 if (delta_usec == 0) {
246 return 0;
247 }
248
249#define SMBPROFILE_STATS_START
250#define SMBPROFILE_STATS_SECTION_START(name, display)
251#define SMBPROFILE_STATS_COUNT(name) do { \
252 count += print_count_count_samples(buf, sizeof(buf), \
253 #name, \
254 &current->values.name##_stats, \
255 &last->values.name##_stats, \
256 delta_usec); \
257} while(0);
258#define SMBPROFILE_STATS_TIME(name) do { \
259} while(0);
260#define SMBPROFILE_STATS_BASIC(name) do { \
261 count += print_basic_count_samples(buf, sizeof(buf), \
262 #name, \
263 &current->values.name##_stats, \
264 &last->values.name##_stats, \
265 delta_usec); \
266} while(0);
267#define SMBPROFILE_STATS_BYTES(name) do { \
268 count += print_bytes_count_samples(buf, sizeof(buf), \
269 #name, \
270 &current->values.name##_stats, \
271 &last->values.name##_stats, \
272 delta_usec); \
273} while(0);
274#define SMBPROFILE_STATS_IOBYTES(name) do { \
275 count += print_iobytes_count_samples(buf, sizeof(buf), \
276 #name, \
277 &current->values.name##_stats, \
278 &last->values.name##_stats, \
279 delta_usec); \
280} while(0);
281#define SMBPROFILE_STATS_SECTION_END
282#define SMBPROFILE_STATS_END
283 SMBPROFILE_STATS_ALL_SECTIONS
284#undef SMBPROFILE_STATS_START
285#undef SMBPROFILE_STATS_SECTION_START
286#undef SMBPROFILE_STATS_COUNT
287#undef SMBPROFILE_STATS_TIME
288#undef SMBPROFILE_STATS_BASIC
289#undef SMBPROFILE_STATS_BYTES
290#undef SMBPROFILE_STATS_IOBYTES
291#undef SMBPROFILE_STATS_SECTION_END
292#undef SMBPROFILE_STATS_END
293
294 if (buf[0] != '\0') {
295 printf("%-40s\n", buf);
296 buf[0] = '\0';
297 }
298
299 return count;
300}
301
302static struct profile_stats sample_data[2];
303static uint64_t sample_time[2];
304
305bool status_profile_rates(bool verbose)
306{
307 uint64_t remain_usec;
308 uint64_t next_usec;
309 uint64_t delta_usec;
310
311 int last = 0;
312 int current = 1;
313 int tmp;
314
315 if (verbose) {
316 fprintf(stderr, "Sampling stats at %d sec intervals\n",
317 usec_to_sec(sample_interval_usec));
318 }
319
320 if (!profile_setup(NULL, True)) {
321 fprintf(stderr,"Failed to initialise profile memory\n");
322 return False;
323 }
324
325 smbprofile_collect(&sample_data[last]);
326 for (;;) {
327 sample_time[current] = profile_timestamp();
328 next_usec = sample_time[current] + sample_interval_usec;
329
330 /* Take a sample. */
331 smbprofile_collect(&sample_data[current]);
332
333 /* Rate convert some values and print results. */
334 delta_usec = sample_time[current] - sample_time[last];
335
336 if (print_count_samples(&sample_data[current],
337 &sample_data[last], delta_usec)) {
338 printf("\n");
339 }
340
341 /* Swap sampling buffers. */
342 tmp = last;
343 last = current;
344 current = tmp;
345
346 /* Delay until next sample time. */
347 remain_usec = next_usec - profile_timestamp();
348 if (remain_usec > sample_interval_usec) {
349 fprintf(stderr, "eek! falling behind sampling rate!\n");
350 } else {
351 if (verbose) {
352 fprintf(stderr,
353 "delaying for %lu msec\n",
354 (unsigned long )usec_to_msec(remain_usec));
355 }
356
357 usleep(remain_usec);
358 }
359
360 }
361
362 return True;
363}
Note: See TracBrowser for help on using the repository browser.