This source file includes following definitions.
- linux_module_init
- linux_module_fini
- next_field
- convert_value
- query
- local_getline
- local_stripper
- local_getfields
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 #include "opal_config.h"
  26 #include "opal/constants.h"
  27 
  28 
  29 
  30 #include <stdio.h>
  31 #include <fcntl.h>
  32 #include <unistd.h>
  33 #include <stdlib.h>
  34 #include <string.h>
  35 #include <errno.h>
  36 #include <ctype.h>
  37 #include <time.h>
  38 #ifdef HAVE_SYS_TIME_H
  39 #include <sys/time.h>
  40 #endif
  41 
  42 #include <sys/param.h>  
  43 
  44 #include "opal/dss/dss_types.h"
  45 #include "opal/util/argv.h"
  46 #include "opal/util/printf.h"
  47 
  48 #include "pstat_linux.h"
  49 
  50 
  51 
  52 
  53 static int linux_module_init(void);
  54 static int query(pid_t pid,
  55                  opal_pstats_t *stats,
  56                  opal_node_stats_t *nstats);
  57 static int linux_module_fini(void);
  58 
  59 
  60 
  61 
  62 const opal_pstat_base_module_t opal_pstat_linux_module = {
  63     
  64     linux_module_init,
  65     query,
  66     linux_module_fini
  67 };
  68 
  69 #define OPAL_STAT_MAX_LENGTH   1024
  70 
  71 
  72 static char *local_getline(FILE *fp);
  73 static char *local_stripper(char *data);
  74 static void local_getfields(char *data, char ***fields);
  75 
  76 
  77 static char input[OPAL_STAT_MAX_LENGTH];
  78 
  79 static int linux_module_init(void)
  80 {
  81     return OPAL_SUCCESS;
  82 }
  83 
  84 static int linux_module_fini(void)
  85 {
  86     return OPAL_SUCCESS;
  87 }
  88 
  89 static char *next_field(char *ptr, int barrier)
  90 {
  91     int i=0;
  92 
  93     
  94 
  95 
  96     while (!isspace(*ptr) && i < barrier) {
  97         ptr++;  
  98         i++;
  99     }
 100 
 101     
 102     while (isspace(*ptr) && i < barrier) {
 103         ptr++;
 104         i++;
 105     }
 106 
 107     return ptr;
 108 }
 109 
 110 static float convert_value(char *value)
 111 {
 112     char *ptr;
 113     float fval;
 114 
 115     
 116     fval = (float)strtoul(value, &ptr, 10);
 117     
 118     if (NULL != ptr && NULL != strstr(ptr, "kB")) {
 119         fval /= 1024.0;
 120     }
 121     return fval;
 122 }
 123 
 124 static int query(pid_t pid,
 125                  opal_pstats_t *stats,
 126                  opal_node_stats_t *nstats)
 127 {
 128     char data[4096];
 129     int fd;
 130     size_t numchars;
 131     char *ptr, *eptr;
 132     int i;
 133     int len, itime;
 134     double dtime;
 135     FILE *fp;
 136     char *dptr, *value;
 137     char **fields;
 138     opal_diskstats_t *ds;
 139     opal_netstats_t *ns;
 140 
 141     if (NULL != stats) {
 142         
 143         gettimeofday(&stats->sample_time, NULL);
 144         
 145 
 146 
 147         if (NULL != nstats) {
 148             nstats->sample_time.tv_sec = stats->sample_time.tv_sec;
 149             nstats->sample_time.tv_usec = stats->sample_time.tv_usec;
 150         }
 151     } else if (NULL != nstats) {
 152         
 153         gettimeofday(&nstats->sample_time, NULL);
 154     }
 155 
 156     if (NULL != stats) {
 157         
 158         numchars = snprintf(data, sizeof(data), "/proc/%d/stat", pid);
 159         if (numchars >= sizeof(data)) {
 160             return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 161         }
 162 
 163         if (0 > (fd = open(data, O_RDONLY))) {
 164             
 165 
 166 
 167 
 168             return OPAL_ERR_FILE_OPEN_FAILURE;
 169         }
 170 
 171         
 172 
 173 
 174         memset(data, 0, sizeof(data));
 175         len = read(fd, data, sizeof(data)-1);
 176         if (len < 0) {
 177             
 178             close(fd);
 179             return OPAL_ERR_FILE_OPEN_FAILURE;
 180         }
 181         close(fd);
 182 
 183         
 184         data[len] = '\0';
 185 
 186         
 187 
 188 
 189 
 190         
 191         stats->pid = pid;
 192 
 193         
 194         if (NULL == (ptr = strchr(data, '('))) {
 195             
 196             return OPAL_ERR_BAD_PARAM;
 197         }
 198         
 199         ptr++;
 200 
 201         
 202         if (NULL == (eptr = strchr(ptr, ')'))) {
 203             
 204             return OPAL_ERR_BAD_PARAM;
 205         }
 206 
 207         
 208         i = 0;
 209         while (ptr < eptr && i < OPAL_PSTAT_MAX_STRING_LEN) {
 210             stats->cmd[i++] = *ptr++;
 211         }
 212 
 213         
 214         ptr = next_field(eptr, len);
 215 
 216         
 217         stats->state[0] = *ptr;
 218         
 219         ptr = next_field(ptr, len);
 220 
 221         
 222         ptr = next_field(ptr, len); 
 223         ptr = next_field(ptr, len); 
 224         ptr = next_field(ptr, len); 
 225         ptr = next_field(ptr, len); 
 226         ptr = next_field(ptr, len); 
 227         ptr = next_field(ptr, len); 
 228         ptr = next_field(ptr, len); 
 229         ptr = next_field(ptr, len); 
 230         ptr = next_field(ptr, len); 
 231         ptr = next_field(ptr, len); 
 232 
 233         
 234         itime = strtoul(ptr, &ptr, 10);    
 235         itime += strtoul(ptr, &ptr, 10);   
 236         
 237         dtime = (double)itime / (double)HZ;
 238         stats->time.tv_sec = (int)dtime;
 239         stats->time.tv_usec = (int)(1000000.0 * (dtime - stats->time.tv_sec));
 240         
 241         ptr = next_field(ptr, len);
 242 
 243         
 244         ptr = next_field(ptr, len); 
 245         ptr = next_field(ptr, len); 
 246 
 247         
 248         stats->priority = strtol(ptr, &ptr, 10);
 249         
 250         ptr = next_field(ptr, len);
 251 
 252         
 253         ptr = next_field(ptr, len);
 254 
 255         
 256         stats->num_threads = strtoul(ptr, &ptr, 10);
 257         
 258         ptr = next_field(ptr, len);
 259 
 260         
 261         ptr = next_field(ptr, len);  
 262         ptr = next_field(ptr, len);  
 263         ptr = next_field(ptr, len);  
 264         ptr = next_field(ptr, len);  
 265         ptr = next_field(ptr, len);  
 266         ptr = next_field(ptr, len);  
 267         ptr = next_field(ptr, len);  
 268         ptr = next_field(ptr, len);  
 269         ptr = next_field(ptr, len);  
 270         ptr = next_field(ptr, len);  
 271         ptr = next_field(ptr, len);  
 272         ptr = next_field(ptr, len);  
 273         ptr = next_field(ptr, len);  
 274         ptr = next_field(ptr, len);  
 275         ptr = next_field(ptr, len);  
 276         ptr = next_field(ptr, len);  
 277         ptr = next_field(ptr, len);  
 278         ptr = next_field(ptr, len);  
 279 
 280         
 281         stats->processor = strtol(ptr, NULL, 10);
 282 
 283         
 284 
 285         
 286         memset(data, 0, sizeof(data));
 287         numchars = snprintf(data, sizeof(data), "/proc/%d/status", pid);
 288         if (numchars >= sizeof(data)) {
 289             return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 290         }
 291 
 292         if (NULL == (fp = fopen(data, "r"))) {
 293             
 294             return OPAL_SUCCESS;
 295         }
 296 
 297         
 298         while (NULL != (dptr = local_getline(fp))) {
 299             if (NULL == (value = local_stripper(dptr))) {
 300                 
 301                 continue;
 302             }
 303             
 304             if (0 == strncmp(dptr, "VmPeak", strlen("VmPeak"))) {
 305                 stats->peak_vsize = convert_value(value);
 306             } else if (0 == strncmp(dptr, "VmSize", strlen("VmSize"))) {
 307                 stats->vsize = convert_value(value);
 308             } else if (0 == strncmp(dptr, "VmRSS", strlen("VmRSS"))) {
 309                 stats->rss = convert_value(value);
 310             }
 311         }
 312         fclose(fp);
 313 
 314         
 315         memset(data, 0, sizeof(data));
 316         numchars = snprintf(data, sizeof(data), "/proc/%d/smaps", pid);
 317         if (numchars >= sizeof(data)) {
 318             return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 319         }
 320 
 321         if (NULL == (fp = fopen(data, "r"))) {
 322             
 323             return OPAL_SUCCESS;
 324         }
 325 
 326         
 327         while (NULL != (dptr = local_getline(fp))) {
 328             if (NULL == (value = local_stripper(dptr))) {
 329                 
 330                 continue;
 331             }
 332             
 333             if (0 == strncmp(dptr, "Pss", strlen("Pss"))) {
 334                 stats->pss += convert_value(value);
 335             }
 336         }
 337         fclose(fp);
 338     }
 339 
 340     if (NULL != nstats) {
 341         
 342         if (0 > (fd = open("/proc/loadavg", O_RDONLY))) {
 343             
 344 
 345 
 346             goto diskstats;
 347         }
 348 
 349         
 350 
 351 
 352         memset(data, 0, sizeof(data));
 353         len = read(fd, data, sizeof(data)-1);
 354         close(fd);
 355         if (len < 0) {
 356             goto diskstats;
 357         }
 358 
 359         
 360         data[len] = '\0';
 361 
 362         
 363         nstats->la = strtof(data, &ptr);
 364         nstats->la5 = strtof(ptr, &eptr);
 365         nstats->la15 = strtof(eptr, NULL);
 366 
 367         
 368         if (NULL == (fp = fopen("/proc/meminfo", "r"))) {
 369             
 370             goto diskstats;
 371         }
 372 
 373         
 374         while (NULL != (dptr = local_getline(fp))) {
 375             if (NULL == (value = local_stripper(dptr))) {
 376                 
 377                 continue;
 378             }
 379             if (0 == strcmp(dptr, "MemTotal")) {
 380                 nstats->total_mem = convert_value(value);
 381             } else if (0 == strcmp(dptr, "MemFree")) {
 382                 nstats->free_mem = convert_value(value);
 383             } else if (0 == strcmp(dptr, "Buffers")) {
 384                 nstats->buffers = convert_value(value);
 385             } else if (0 == strcmp(dptr, "Cached")) {
 386                 nstats->cached = convert_value(value);
 387             } else if (0 == strcmp(dptr, "SwapCached")) {
 388                 nstats->swap_cached = convert_value(value);
 389             } else if (0 == strcmp(dptr, "SwapTotal")) {
 390                 nstats->swap_total = convert_value(value);
 391             } else if (0 == strcmp(dptr, "SwapFree")) {
 392                 nstats->swap_free = convert_value(value);
 393             } else if (0 == strcmp(dptr, "Mapped")) {
 394                 nstats->mapped = convert_value(value);
 395             }
 396         }
 397         fclose(fp);
 398 
 399     diskstats:
 400         
 401         if (NULL == (fp = fopen("/proc/diskstats", "r"))) {
 402             
 403 
 404 
 405             goto netstats;
 406         }
 407         
 408         while (NULL != (dptr = local_getline(fp))) {
 409             
 410             if (NULL == strstr(dptr, "sd")) {
 411                 continue;
 412             }
 413             
 414             fields = NULL;
 415             local_getfields(dptr, &fields);
 416             if (NULL == fields) {
 417                 continue;
 418             }
 419             if (14 < opal_argv_count(fields)) {
 420                 opal_argv_free(fields);
 421                 continue;
 422             }
 423             
 424             ds = OBJ_NEW(opal_diskstats_t);
 425             ds->disk = strdup(fields[2]);
 426             ds->num_reads_completed = strtoul(fields[3], NULL, 10);
 427             ds->num_reads_merged = strtoul(fields[4], NULL, 10);
 428             ds->num_sectors_read = strtoul(fields[5], NULL, 10);
 429             ds->milliseconds_reading = strtoul(fields[6], NULL, 10);
 430             ds->num_writes_completed = strtoul(fields[7], NULL, 10);
 431             ds->num_writes_merged = strtoul(fields[8], NULL, 10);
 432             ds->num_sectors_written = strtoul(fields[9], NULL, 10);
 433             ds->milliseconds_writing = strtoul(fields[10], NULL, 10);
 434             ds->num_ios_in_progress = strtoul(fields[11], NULL, 10);
 435             ds->milliseconds_io = strtoul(fields[12], NULL, 10);
 436             ds->weighted_milliseconds_io = strtoul(fields[13], NULL, 10);
 437             opal_list_append(&nstats->diskstats, &ds->super);
 438             opal_argv_free(fields);
 439         }
 440         fclose(fp);
 441 
 442     netstats:
 443         
 444         if (NULL == (fp = fopen("/proc/net/dev", "r"))) {
 445             
 446 
 447 
 448             goto complete;
 449         }
 450         
 451         local_getline(fp);
 452         local_getline(fp);
 453         
 454         while (NULL != (dptr = local_getline(fp))) {
 455             
 456             if (NULL == (ptr = strchr(dptr, ':'))) {
 457                 continue;
 458             }
 459             *ptr = '\0';
 460             ptr++;
 461             
 462             fields = NULL;
 463             local_getfields(ptr, &fields);
 464             if (NULL == fields) {
 465                 continue;
 466             }
 467             
 468             ns = OBJ_NEW(opal_netstats_t);
 469             ns->net_interface = strdup(dptr);
 470             ns->num_bytes_recvd = strtoul(fields[0], NULL, 10);
 471             ns->num_packets_recvd = strtoul(fields[1], NULL, 10);
 472             ns->num_recv_errs = strtoul(fields[2], NULL, 10);
 473             ns->num_bytes_sent = strtoul(fields[8], NULL, 10);
 474             ns->num_packets_sent = strtoul(fields[9], NULL, 10);
 475             ns->num_send_errs = strtoul(fields[10], NULL, 10);
 476             opal_list_append(&nstats->netstats, &ns->super);
 477             opal_argv_free(fields);
 478         }
 479         fclose(fp);
 480     }
 481 
 482  complete:
 483     return OPAL_SUCCESS;
 484 }
 485 
 486 static char *local_getline(FILE *fp)
 487 {
 488     char *ret, *ptr;
 489 
 490     ret = fgets(input, OPAL_STAT_MAX_LENGTH, fp);
 491     if (NULL != ret) {
 492         input[strlen(input)-1] = '\0';  
 493         
 494         ptr = input;
 495         while (!isalnum(*ptr)) {
 496             ptr++;
 497         }
 498         return ptr;
 499     }
 500 
 501     return NULL;
 502 }
 503 
 504 static char *local_stripper(char *data)
 505 {
 506     char *ptr, *end, *enddata;
 507     int len = strlen(data);
 508 
 509     
 510     if (NULL == (end = strchr(data, ':'))) {
 511         return NULL;
 512     }
 513     ptr = end;
 514     --end;
 515     
 516     while (end != data && !isalnum(*end)) {
 517         --end;
 518     }
 519     ++end;
 520     *end = '\0';
 521     
 522     ptr++;
 523     enddata = &(data[len-1]);
 524     while (ptr != enddata && !isalnum(*ptr)) {
 525         ++ptr;
 526     }
 527     return ptr;
 528 }
 529 
 530 static void local_getfields(char *dptr, char ***fields)
 531 {
 532     char *ptr, *end;
 533 
 534     
 535     *fields = NULL;
 536 
 537     
 538     ptr = dptr;
 539     while ('\0' != *ptr && !isalnum(*ptr)) {
 540         ptr++;
 541     }
 542     if ('\0' == *ptr) {
 543         return;
 544     }
 545 
 546     
 547 
 548 
 549 
 550 
 551     end = ptr;  
 552     end++;  
 553     while ('\0' != *end) {
 554         
 555         while ('\0' != *end && isalnum(*end)) {
 556             end++;
 557         }
 558         
 559         *end = '\0';
 560         
 561         opal_argv_append_nosize(fields, ptr);
 562         
 563         end++;
 564         while ('\0' != *end && !isalnum(*end)) {
 565             end++;
 566         }
 567         if ('\0' == *end) {
 568             ptr = NULL;
 569             break;
 570         }
 571         ptr = end;
 572         end++;
 573     }
 574     if (NULL != ptr) {
 575         
 576         opal_argv_append_nosize(fields, ptr);
 577     }
 578 }