1
/* Copyright (c) 2010, 2012 Nicira, Inc.
1
/* Copyright (c) 2010, 2012, 2013 Nicira, Inc.
3
3
* Licensed under the Apache License, Version 2.0 (the "License");
4
4
* you may not use this file except in compliance with the License.
128
133
stream = fopen(file_name, "r");
130
VLOG_WARN_ONCE("%s: open failed (%s)", file_name, strerror(errno));
135
VLOG_WARN_ONCE("%s: open failed (%s)",
136
file_name, ovs_strerror(errno));
180
186
stream = fopen(stat_file, "r");
182
VLOG_ERR_ONCE("%s: open failed (%s)", stat_file, strerror(errno));
188
VLOG_ERR_ONCE("%s: open failed (%s)",
189
stat_file, ovs_strerror(errno));
183
190
return boot_time;
238
245
sprintf(file_name, "/proc/%lu/stat", (unsigned long int) pid);
239
246
stream = fopen(file_name, "r");
241
VLOG_ERR_ONCE("%s: open failed (%s)", file_name, strerror(errno));
248
VLOG_ERR_ONCE("%s: open failed (%s)",
249
file_name, ovs_strerror(errno));
323
331
sprintf(file_name, "/proc/%lu/cmdline", (unsigned long int) pid);
324
332
stream = fopen(file_name, "r");
326
VLOG_WARN_ONCE("%s: open failed (%s)", file_name, strerror(errno));
334
VLOG_WARN_ONCE("%s: open failed (%s)", file_name, ovs_strerror(errno));
330
338
if (!fgets(line, sizeof line, stream)) {
331
339
VLOG_WARN_ONCE("%s: read failed (%s)", file_name,
332
feof(stream) ? "end of file" : strerror(errno));
340
feof(stream) ? "end of file" : ovs_strerror(errno));
395
403
dir = opendir(ovs_rundir());
397
VLOG_ERR_ONCE("%s: open failed (%s)", ovs_rundir(), strerror(errno));
405
VLOG_ERR_ONCE("%s: open failed (%s)",
406
ovs_rundir(), ovs_strerror(errno));
444
453
get_filesys_stats(struct smap *stats OVS_UNUSED)
446
#if HAVE_SETMNTENT && HAVE_STATVFS
455
#if HAVE_GETMNTENT_R && HAVE_STATVFS
447
456
static const char file_name[] = "/etc/mtab";
457
struct mntent mntent;
448
458
struct mntent *me;
452
463
stream = setmntent(file_name, "r");
454
VLOG_ERR_ONCE("%s: open failed (%s)", file_name, strerror(errno));
465
VLOG_ERR_ONCE("%s: open failed (%s)", file_name, ovs_strerror(errno));
459
while ((me = getmntent(stream)) != NULL) {
470
while ((me = getmntent_r(stream, &mntent, buf, sizeof buf)) != NULL) {
460
471
unsigned long long int total, free;
461
472
struct statvfs vfs;
490
501
smap_add(stats, "file_systems", ds_cstr(&s));
493
#endif /* HAVE_SETMNTENT && HAVE_STATVFS */
504
#endif /* HAVE_GETMNTENT_R && HAVE_STATVFS */
496
507
#define SYSTEM_STATS_INTERVAL (5 * 1000) /* In milliseconds. */
498
/* Whether the client wants us to report system stats. */
509
static struct ovs_mutex mutex = OVS_ADAPTIVE_MUTEX_INITIALIZER;
510
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
511
static struct latch latch OVS_GUARDED_BY(mutex);
499
512
static bool enabled;
502
S_DISABLED, /* Not enabled, nothing going on. */
503
S_WAITING, /* Sleeping for SYSTEM_STATS_INTERVAL ms. */
504
S_REQUEST_SENT, /* Sent a request to worker. */
505
S_REPLY_RECEIVED /* Received a reply from worker. */
508
/* In S_WAITING state: the next time to wake up.
509
* In other states: not meaningful. */
510
static long long int next_refresh;
512
/* In S_REPLY_RECEIVED: the stats that have just been received.
513
* In other states: not meaningful. */
514
static struct smap *received_stats;
516
static worker_request_func system_stats_request_cb;
517
static worker_reply_func system_stats_reply_cb;
519
/* Enables or disables system stats collection, according to 'new_enable'.
521
* Even if system stats are disabled, the caller should still periodically call
522
* system_stats_run(). */
513
static bool started OVS_GUARDED_BY(mutex);
514
static struct smap *system_stats OVS_GUARDED_BY(mutex);
516
static void *system_stats_thread_func(void *);
517
static void discard_stats(void);
519
/* Enables or disables system stats collection, according to 'enable'. */
524
system_stats_enable(bool new_enable)
521
system_stats_enable(bool enable)
526
if (new_enable != enabled) {
528
if (state == S_DISABLED) {
530
next_refresh = time_msec();
533
if (state == S_WAITING) {
523
if (enabled != enable) {
524
ovs_mutex_lock(&mutex);
527
xpthread_create(NULL, NULL, system_stats_thread_func, NULL);
532
xpthread_cond_signal(&cond);
537
enabled = new_enable;
535
ovs_mutex_unlock(&mutex);
544
542
* When a new snapshot is available (which only occurs if system stats are
545
543
* enabled), returns it as an smap owned by the caller. The caller must use
546
* both smap_destroy() and free() to complete free the returned data.
544
* both smap_destroy() and free() to completely free the returned data.
548
546
* When no new snapshot is available, returns NULL. */
550
548
system_stats_run(void)
557
if (time_msec() >= next_refresh) {
558
worker_request(NULL, 0, NULL, 0, system_stats_request_cb,
559
system_stats_reply_cb, NULL);
560
state = S_REQUEST_SENT;
567
case S_REPLY_RECEIVED:
550
struct smap *stats = NULL;
552
ovs_mutex_lock(&mutex);
570
next_refresh = time_msec() + SYSTEM_STATS_INTERVAL;
571
return received_stats;
557
stats = system_stats;
573
smap_destroy(received_stats);
574
free(received_stats);
563
ovs_mutex_unlock(&mutex);
583
568
/* Causes poll_block() to wake up when system_stats_run() needs to be
586
571
system_stats_wait(void)
593
poll_timer_wait_until(next_refresh);
597
/* Someone else should be calling worker_wait() to wake up when the
598
* reply arrives, otherwise there's a bug. */
601
case S_REPLY_RECEIVED:
602
poll_immediate_wake();
608
system_stats_request_cb(struct ofpbuf *request OVS_UNUSED,
609
const int fds[] OVS_UNUSED, size_t n_fds OVS_UNUSED)
616
get_cpu_cores(&stats);
617
get_load_average(&stats);
618
get_memory_stats(&stats);
619
get_process_stats(&stats);
620
get_filesys_stats(&stats);
622
json = smap_to_json(&stats);
623
s = json_to_string(json, 0);
624
worker_reply(s, strlen(s) + 1, NULL, 0);
628
smap_destroy(&stats);
632
system_stats_reply_cb(struct ofpbuf *reply,
633
const int fds[] OVS_UNUSED, size_t n_fds OVS_UNUSED,
634
void *aux OVS_UNUSED)
636
struct json *json = json_from_string(reply->data);
638
received_stats = xmalloc(sizeof *received_stats);
639
smap_init(received_stats);
640
smap_from_json(received_stats, json);
642
ovs_assert(state == S_REQUEST_SENT);
643
state = S_REPLY_RECEIVED;
579
discard_stats(void) OVS_REQUIRES(&mutex)
582
smap_destroy(system_stats);
588
static void * NO_RETURN
589
system_stats_thread_func(void *arg OVS_UNUSED)
591
pthread_detach(pthread_self());
594
long long int next_refresh;
597
ovs_mutex_lock(&mutex);
599
ovs_mutex_cond_wait(&cond, &mutex);
601
ovs_mutex_unlock(&mutex);
603
stats = xmalloc(sizeof *stats);
605
get_cpu_cores(stats);
606
get_load_average(stats);
607
get_memory_stats(stats);
608
get_process_stats(stats);
609
get_filesys_stats(stats);
611
ovs_mutex_lock(&mutex);
613
system_stats = stats;
615
ovs_mutex_unlock(&mutex);
617
next_refresh = time_msec() + SYSTEM_STATS_INTERVAL;
619
poll_timer_wait_until(next_refresh);
621
} while (time_msec() < next_refresh);