1
1

Extend the node statistics to include disk and network traffic data.

This commit was SVN r27834.
Этот коммит содержится в:
Ralph Castain 2013-01-15 22:42:36 +00:00
родитель 54266837e9
Коммит f29f1b731c
3 изменённых файлов: 220 добавлений и 9 удалений

Просмотреть файл

@ -10,7 +10,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -146,6 +146,34 @@ OBJ_CLASS_INSTANCE(opal_pstats_t, opal_list_item_t,
opal_pstat_construct,
NULL);
static void diskstat_cons(opal_diskstats_t *ptr)
{
ptr->disk = NULL;
}
static void diskstat_dest(opal_diskstats_t *ptr)
{
if (NULL != ptr->disk) {
free(ptr->disk);
}
}
OBJ_CLASS_INSTANCE(opal_diskstats_t,
opal_list_item_t,
diskstat_cons, diskstat_dest);
static void netstat_cons(opal_netstats_t *ptr)
{
ptr->interface = NULL;
}
static void netstat_dest(opal_netstats_t *ptr)
{
if (NULL != ptr->interface) {
free(ptr->interface);
}
}
OBJ_CLASS_INSTANCE(opal_netstats_t,
opal_list_item_t,
netstat_cons, netstat_dest);
static void opal_node_stats_construct(opal_node_stats_t *obj)
{
obj->la = 0.0;
@ -161,10 +189,24 @@ static void opal_node_stats_construct(opal_node_stats_t *obj)
obj->mapped = 0.0;
obj->sample_time.tv_sec = 0;
obj->sample_time.tv_usec = 0;
OBJ_CONSTRUCT(&obj->diskstats, opal_list_t);
OBJ_CONSTRUCT(&obj->netstats, opal_list_t);
}
static void opal_node_stats_destruct(opal_node_stats_t *obj)
{
opal_list_item_t *item;
while (NULL != (item = opal_list_remove_first(&obj->diskstats))) {
OBJ_RELEASE(item);
}
OBJ_DESTRUCT(&obj->diskstats);
while (NULL != (item = opal_list_remove_first(&obj->netstats))) {
OBJ_RELEASE(item);
}
OBJ_DESTRUCT(&obj->netstats);
}
OBJ_CLASS_INSTANCE(opal_node_stats_t, opal_object_t,
opal_node_stats_construct,
NULL);
opal_node_stats_destruct);
int opal_dss_open(void)

Просмотреть файл

@ -11,7 +11,7 @@
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007-2011 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -34,6 +34,7 @@
#endif
#include "opal/class/opal_object.h"
#include "opal/class/opal_pointer_array.h"
#include "opal/class/opal_list.h"
BEGIN_C_DECLS
@ -139,6 +140,31 @@ typedef struct {
struct timeval sample_time;
} opal_pstats_t;
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_pstats_t);
typedef struct {
opal_list_item_t super;
char *disk;
unsigned long num_reads_completed;
unsigned long num_reads_merged;
unsigned long num_sectors_read;
unsigned long milliseconds_reading;
unsigned long num_writes_completed;
unsigned long num_writes_merged;
unsigned long num_sectors_written;
unsigned long milliseconds_writing;
unsigned long num_ios_in_progress;
unsigned long milliseconds_io;
unsigned long weighted_milliseconds_io;
} opal_diskstats_t;
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_diskstats_t);
typedef struct {
opal_list_item_t super;
char *interface;
unsigned long num_bytes_read;
unsigned long num_packets_read;
unsigned long num_bytes_sent;
unsigned long num_packets_sent;
} opal_netstats_t;
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_netstats_t);
typedef struct {
opal_object_t super;
/* node-level load averages */
@ -156,6 +182,11 @@ typedef struct {
float mapped; /* in MBytes */
/* time at which sample was taken */
struct timeval sample_time;
/* list of disk stats, one per disk */
opal_list_t diskstats;
/* list of net stats, one per interface */
opal_list_t netstats;
} opal_node_stats_t;
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_node_stats_t);

Просмотреть файл

@ -10,6 +10,7 @@
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights reserved.
*
* $COPYRIGHT$
*
@ -41,6 +42,7 @@
#include "opal/mca/base/mca_base_param.h"
#include "opal/dss/dss_types.h"
#include "opal/util/argv.h"
#include "opal/util/printf.h"
#include "pstat_linux.h"
@ -64,12 +66,15 @@ const opal_pstat_base_module_t opal_pstat_linux_module = {
linux_module_fini
};
#define OPAL_STAT_MAX_LENGTH 1024
/* Local functions */
static char *local_getline(FILE *fp);
static char *local_stripper(char *data);
static void local_getfields(char *data, char ***fields);
/* Local data */
static char input[256];
static char input[OPAL_STAT_MAX_LENGTH];
static int linux_module_init(void)
{
@ -129,6 +134,9 @@ static int query(pid_t pid,
double dtime;
FILE *fp;
char *dptr, *value;
char **fields;
opal_diskstats_t *ds;
opal_netstats_t *ns;
if (NULL != stats) {
/* record the time of this sample */
@ -310,7 +318,7 @@ static int query(pid_t pid,
/* not an error if we don't find this one as it
* isn't critical
*/
return OPAL_SUCCESS;
goto diskstats;
}
/* absorb all of the file's contents in one gulp - we'll process
@ -331,7 +339,7 @@ static int query(pid_t pid,
/* see if we can open the meminfo file */
if (NULL == (fp = fopen("/proc/meminfo", "r"))) {
/* ignore this */
return OPAL_SUCCESS;
goto diskstats;
}
/* read the file one line at a time */
@ -359,19 +367,99 @@ static int query(pid_t pid,
}
}
fclose(fp);
diskstats:
/* look for the diskstats file */
if (NULL == (fp = fopen("/proc/diskstats", "r"))) {
/* not an error if we don't find this one as it
* isn't critical
*/
goto netstats;
}
/* read the file one line at a time */
while (NULL != (dptr = local_getline(fp))) {
/* look for the local disks */
if (NULL == strstr(dptr, "sd")) {
continue;
}
/* parse to extract the fields */
fields = NULL;
local_getfields(dptr, &fields);
if (NULL == fields || 14 < opal_argv_count(fields)) {
continue;
}
/* pack the ones of interest into the struct */
ds = OBJ_NEW(opal_diskstats_t);
ds->disk = strdup(fields[2]);
ds->num_reads_completed = strtoul(fields[3], NULL, 10);
ds->num_reads_merged = strtoul(fields[4], NULL, 10);
ds->num_sectors_read = strtoul(fields[5], NULL, 10);
ds->milliseconds_reading = strtoul(fields[6], NULL, 10);
ds->num_writes_completed = strtoul(fields[7], NULL, 10);
ds->num_writes_merged = strtoul(fields[8], NULL, 10);
ds->num_sectors_written = strtoul(fields[9], NULL, 10);
ds->milliseconds_writing = strtoul(fields[10], NULL, 10);
ds->num_ios_in_progress = strtoul(fields[11], NULL, 10);
ds->milliseconds_io = strtoul(fields[12], NULL, 10);
ds->weighted_milliseconds_io = strtoul(fields[13], NULL, 10);
opal_list_append(&nstats->diskstats, &ds->super);
opal_argv_free(fields);
}
netstats:
/* look for the netstats file */
if (NULL == (fp = fopen("/proc/net/dev", "r"))) {
/* not an error if we don't find this one as it
* isn't critical
*/
goto complete;
}
/* skip the first two lines as they are headers */
local_getline(fp);
local_getline(fp);
/* read the file one line at a time */
while (NULL != (dptr = local_getline(fp))) {
/* the interface is at the start of the line */
if (NULL == (ptr = strchr(dptr, ':'))) {
continue;
}
*ptr = '\0';
ptr++;
/* parse to extract the fields */
fields = NULL;
local_getfields(ptr, &fields);
if (NULL == fields) {
continue;
}
/* pack the ones of interest into the struct */
ns = OBJ_NEW(opal_netstats_t);
ns->interface = strdup(dptr);
ns->num_bytes_read = strtoul(fields[0], NULL, 10);
ns->num_packets_read = strtoul(fields[1], NULL, 10);
ns->num_bytes_sent = strtoul(fields[8], NULL, 10);
ns->num_packets_sent = strtoul(fields[9], NULL, 10);
opal_list_append(&nstats->netstats, &ns->super);
opal_argv_free(fields);
}
}
complete:
return OPAL_SUCCESS;
}
static char *local_getline(FILE *fp)
{
char *ret;
char *ret, *ptr;
ret = fgets(input, 256, fp);
ret = fgets(input, OPAL_STAT_MAX_LENGTH, fp);
if (NULL != ret) {
input[strlen(input)-1] = '\0'; /* remove newline */
return input;
/* strip leading white space */
ptr = input;
while (!isalnum(*ptr)) {
ptr++;
}
return ptr;
}
return NULL;
@ -402,3 +490,53 @@ static char *local_stripper(char *data)
}
return ptr;
}
static void local_getfields(char *dptr, char ***fields)
{
char *ptr, *end;
/* set default */
*fields = NULL;
/* find the beginning */
ptr = dptr;
while ('\0' != *ptr && !isalnum(*ptr)) {
ptr++;
}
if ('\0' == *ptr) {
return;
}
/* working from this point, find the end of each
* alpha-numeric field and store it on the stack.
* Then shift across the white space to the start
* of the next one
*/
end = ptr; /* ptr points to an alnum */
end++; /* look at next character */
while ('\0' != *end) {
/* find the end of this alpha string */
while ('\0' != *end && isalnum(*end)) {
end++;
}
/* terminate it */
*end = '\0';
/* store it on the stack */
opal_argv_append_nosize(fields, ptr);
/* step across any white space */
end++;
while ('\0' != *end && !isalnum(*end)) {
end++;
}
if ('\0' == *end) {
ptr = NULL;
break;
}
ptr = end;
end++;
}
if (NULL != ptr) {
/* have a hanging field */
opal_argv_append_nosize(fields, ptr);
}
}