Extend the node statistics to include disk and network traffic data.
This commit was SVN r27834.
Этот коммит содержится в:
родитель
54266837e9
Коммит
f29f1b731c
@ -10,7 +10,7 @@
|
|||||||
* University of Stuttgart. All rights reserved.
|
* University of Stuttgart. All rights reserved.
|
||||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
* All rights reserved.
|
* 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$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -146,6 +146,34 @@ OBJ_CLASS_INSTANCE(opal_pstats_t, opal_list_item_t,
|
|||||||
opal_pstat_construct,
|
opal_pstat_construct,
|
||||||
NULL);
|
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)
|
static void opal_node_stats_construct(opal_node_stats_t *obj)
|
||||||
{
|
{
|
||||||
obj->la = 0.0;
|
obj->la = 0.0;
|
||||||
@ -161,10 +189,24 @@ static void opal_node_stats_construct(opal_node_stats_t *obj)
|
|||||||
obj->mapped = 0.0;
|
obj->mapped = 0.0;
|
||||||
obj->sample_time.tv_sec = 0;
|
obj->sample_time.tv_sec = 0;
|
||||||
obj->sample_time.tv_usec = 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,
|
OBJ_CLASS_INSTANCE(opal_node_stats_t, opal_object_t,
|
||||||
opal_node_stats_construct,
|
opal_node_stats_construct,
|
||||||
NULL);
|
opal_node_stats_destruct);
|
||||||
|
|
||||||
|
|
||||||
int opal_dss_open(void)
|
int opal_dss_open(void)
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2007-2011 Cisco Systems, Inc. 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$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -34,6 +34,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "opal/class/opal_object.h"
|
#include "opal/class/opal_object.h"
|
||||||
|
#include "opal/class/opal_pointer_array.h"
|
||||||
#include "opal/class/opal_list.h"
|
#include "opal/class/opal_list.h"
|
||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
@ -139,6 +140,31 @@ typedef struct {
|
|||||||
struct timeval sample_time;
|
struct timeval sample_time;
|
||||||
} opal_pstats_t;
|
} opal_pstats_t;
|
||||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(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 {
|
typedef struct {
|
||||||
opal_object_t super;
|
opal_object_t super;
|
||||||
/* node-level load averages */
|
/* node-level load averages */
|
||||||
@ -156,6 +182,11 @@ typedef struct {
|
|||||||
float mapped; /* in MBytes */
|
float mapped; /* in MBytes */
|
||||||
/* time at which sample was taken */
|
/* time at which sample was taken */
|
||||||
struct timeval sample_time;
|
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_node_stats_t;
|
||||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(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.
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2006-2007 Cisco Systems, Inc. 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$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -41,6 +42,7 @@
|
|||||||
|
|
||||||
#include "opal/mca/base/mca_base_param.h"
|
#include "opal/mca/base/mca_base_param.h"
|
||||||
#include "opal/dss/dss_types.h"
|
#include "opal/dss/dss_types.h"
|
||||||
|
#include "opal/util/argv.h"
|
||||||
#include "opal/util/printf.h"
|
#include "opal/util/printf.h"
|
||||||
|
|
||||||
#include "pstat_linux.h"
|
#include "pstat_linux.h"
|
||||||
@ -64,12 +66,15 @@ const opal_pstat_base_module_t opal_pstat_linux_module = {
|
|||||||
linux_module_fini
|
linux_module_fini
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define OPAL_STAT_MAX_LENGTH 1024
|
||||||
|
|
||||||
/* Local functions */
|
/* Local functions */
|
||||||
static char *local_getline(FILE *fp);
|
static char *local_getline(FILE *fp);
|
||||||
static char *local_stripper(char *data);
|
static char *local_stripper(char *data);
|
||||||
|
static void local_getfields(char *data, char ***fields);
|
||||||
|
|
||||||
/* Local data */
|
/* Local data */
|
||||||
static char input[256];
|
static char input[OPAL_STAT_MAX_LENGTH];
|
||||||
|
|
||||||
static int linux_module_init(void)
|
static int linux_module_init(void)
|
||||||
{
|
{
|
||||||
@ -129,6 +134,9 @@ static int query(pid_t pid,
|
|||||||
double dtime;
|
double dtime;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *dptr, *value;
|
char *dptr, *value;
|
||||||
|
char **fields;
|
||||||
|
opal_diskstats_t *ds;
|
||||||
|
opal_netstats_t *ns;
|
||||||
|
|
||||||
if (NULL != stats) {
|
if (NULL != stats) {
|
||||||
/* record the time of this sample */
|
/* 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
|
/* not an error if we don't find this one as it
|
||||||
* isn't critical
|
* isn't critical
|
||||||
*/
|
*/
|
||||||
return OPAL_SUCCESS;
|
goto diskstats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* absorb all of the file's contents in one gulp - we'll process
|
/* 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 */
|
/* see if we can open the meminfo file */
|
||||||
if (NULL == (fp = fopen("/proc/meminfo", "r"))) {
|
if (NULL == (fp = fopen("/proc/meminfo", "r"))) {
|
||||||
/* ignore this */
|
/* ignore this */
|
||||||
return OPAL_SUCCESS;
|
goto diskstats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the file one line at a time */
|
/* read the file one line at a time */
|
||||||
@ -359,19 +367,99 @@ static int query(pid_t pid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
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;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *local_getline(FILE *fp)
|
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) {
|
if (NULL != ret) {
|
||||||
input[strlen(input)-1] = '\0'; /* remove newline */
|
input[strlen(input)-1] = '\0'; /* remove newline */
|
||||||
return input;
|
/* strip leading white space */
|
||||||
|
ptr = input;
|
||||||
|
while (!isalnum(*ptr)) {
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -402,3 +490,53 @@ static char *local_stripper(char *data)
|
|||||||
}
|
}
|
||||||
return ptr;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user