linux-lustre.c File Reference

A component for the luster filesystem. More...

Include dependency graph for linux-lustre.c:

Go to the source code of this file.

Data Structures

struct  STEALTIME_reg_alloc_t
struct  string_list
struct  lustre_fs
struct  LUSTRE_control_state_t
struct  LUSTRE_context_t

Defines

#define LUSTRE_MAX_COUNTERS   100
#define LUSTRE_MAX_COUNTER_TERMS   LUSTRE_MAX_COUNTERS

Typedefs

typedef counter_info LUSTRE_register_t
typedef counter_info LUSTRE_native_event_entry_t
typedef counter_info LUSTRE_reg_alloc_t

Functions

static int resize_native_table ()
static counter_infoaddCounter (const char *name, const char *desc, const char *unit)
static int addLustreFS (const char *name, const char *procpath_general, const char *procpath_readahead)
static int init_lustre_counters (void)
static void read_lustre_counter ()
static void host_finalize (void)
static int _lustre_init_component (int cidx)
static int _lustre_init_thread (hwd_context_t *ctx)
static int _lustre_shutdown_component (void)
static int _lustre_shutdown_thread (hwd_context_t *ctx)
static int _lustre_init_control_state (hwd_control_state_t *ctl)
static int _lustre_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _lustre_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _lustre_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _lustre_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _lustre_reset (hwd_context_t *ctx, hwd_control_state_t *ctrl)
static int _lustre_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _lustre_set_domain (hwd_control_state_t *cntrl, int domain)
static int _lustre_ntv_code_to_name (unsigned int EventCode, char *name, int len)
static int _lustre_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
static int _lustre_ntv_enum_events (unsigned int *EventCode, int modifier)

Variables

const char proc_base_path [] = "/proc/fs/lustre/"
static counter_info ** lustre_native_table = NULL
static int num_events = 0
static int table_size = 32
static lustre_fsroot_lustre_fs = NULL
papi_vector_t _lustre_vector

Detailed Description

Author:
Haihang You (in collaboration with Michael Kluge, TU Dresden) you@eecs.utk.edu
Heike Jagode jagode@eecs.utk.edu
Vince Weaver vweaver1@eecs.utk.edu

Definition in file linux-lustre.c.


Define Documentation

#define LUSTRE_MAX_COUNTER_TERMS   LUSTRE_MAX_COUNTERS

Definition at line 58 of file linux-lustre.c.

#define LUSTRE_MAX_COUNTERS   100

Definition at line 57 of file linux-lustre.c.


Typedef Documentation

Definition at line 61 of file linux-lustre.c.

Definition at line 62 of file linux-lustre.c.

Definition at line 60 of file linux-lustre.c.


Function Documentation

static int _lustre_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
) [static]

Definition at line 653 of file linux-lustre.c.

00654 {
00655     ( void ) ctx;
00656     ( void ) code;
00657     ( void ) option;
00658 
00659     return PAPI_OK;
00660 }

static int _lustre_init_component ( int  cidx  )  [static]

Definition at line 427 of file linux-lustre.c.

00428 {
00429     SUBDBG("ENTER:\n");
00430     int ret = PAPI_OK;
00431 
00432     resize_native_table();
00433     ret=init_lustre_counters();
00434     if (ret!=PAPI_OK) {
00435        strncpy(_lustre_vector.cmp_info.disabled_reason,
00436            "No lustre filesystems found",PAPI_MAX_STR_LEN);
00437        SUBDBG("EXIT: ret: %d\n", ret);
00438        return ret;
00439     }
00440 
00441     _lustre_vector.cmp_info.num_native_events=num_events;
00442     _lustre_vector.cmp_info.CmpIdx = cidx;
00443 
00444     SUBDBG("EXIT: ret: %d\n", ret);
00445     return ret;
00446 }

Here is the call graph for this function:

static int _lustre_init_control_state ( hwd_control_state_t ctl  )  [static]

Definition at line 497 of file linux-lustre.c.

00498 {
00499     LUSTRE_control_state_t *lustre_ctl = (LUSTRE_control_state_t *)ctl;
00500 
00501     memset(lustre_ctl->start_count,0,sizeof(long long)*LUSTRE_MAX_COUNTERS);
00502     memset(lustre_ctl->current_count,0,sizeof(long long)*LUSTRE_MAX_COUNTERS);
00503 
00504     return PAPI_OK;
00505 }

static int _lustre_init_thread ( hwd_context_t ctx  )  [static]

Definition at line 456 of file linux-lustre.c.

00457 {
00458   (void) ctx;
00459 
00460   return PAPI_OK;
00461 }

static int _lustre_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
) [static]

Definition at line 712 of file linux-lustre.c.

00713 {
00714    SUBDBG("ENTER: EventCode: %#x, name: %p, len: %d\n", EventCode, name, len);
00715   int event=EventCode;
00716 
00717   if (event >=0 && event < num_events) {
00718    strncpy( name, lustre_native_table[event]->description, len-1 );
00719     name[len-1] = '\0';
00720    SUBDBG("EXIT: description: %s\n", name);
00721     return PAPI_OK;
00722   }
00723    SUBDBG("EXIT: PAPI_ENOEVNT\n");
00724   return PAPI_ENOEVNT;
00725 }

static int _lustre_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
) [static]

Definition at line 692 of file linux-lustre.c.

00693 {
00694    SUBDBG("ENTER: EventCode: %#x, name: %p, len: %d\n", EventCode, name, len);
00695   int event=EventCode;
00696 
00697   if (event >=0 && event < num_events) {
00698      strncpy( name, lustre_native_table[event]->name, len-1 );
00699      name[len-1] = '\0';
00700    SUBDBG("EXIT: event name: %s\n", name);
00701      return PAPI_OK;
00702   }
00703    SUBDBG("EXIT: PAPI_ENOEVNT\n");
00704   return PAPI_ENOEVNT;
00705 }

static int _lustre_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
) [static]

Definition at line 732 of file linux-lustre.c.

00733 {
00734    SUBDBG("ENTER: EventCode: %p, modifier: %d\n", EventCode, modifier);
00735 
00736     if ( modifier == PAPI_ENUM_FIRST ) {
00737        if (num_events==0) return PAPI_ENOEVNT;
00738        *EventCode = 0;
00739     SUBDBG("EXIT: *EventCode: %#x\n", *EventCode);
00740        return PAPI_OK;
00741     }
00742 
00743     if ( modifier == PAPI_ENUM_EVENTS ) {
00744         int index = *EventCode;
00745 
00746         if ((index+1 < num_events) && lustre_native_table[index + 1]) {
00747             *EventCode = *EventCode + 1;
00748         SUBDBG("EXIT: *EventCode: %#x\n", *EventCode);
00749             return PAPI_OK;
00750         } else {
00751         SUBDBG("EXIT: PAPI_ENOEVNT\n");
00752             return PAPI_ENOEVNT;
00753         }
00754     } 
00755         
00756 
00757    SUBDBG("EXIT: PAPI_EINVAL\n");
00758     return PAPI_EINVAL;
00759 }

static int _lustre_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
) [static]

Definition at line 588 of file linux-lustre.c.

00590 {
00591     (void) ctx;
00592     ( void ) flags;
00593 
00594     LUSTRE_control_state_t *lustre_ctl = (LUSTRE_control_state_t *)ctl;
00595     int i;
00596 
00597     read_lustre_counter(  );
00598 
00599     for(i=0;i<lustre_ctl->num_events;i++) {
00600        lustre_ctl->current_count[i]=
00601                  lustre_native_table[lustre_ctl->which_counter[i]]->value;
00602        lustre_ctl->difference[i]=lustre_ctl->current_count[i]-
00603                                          lustre_ctl->start_count[i];
00604     }
00605 
00606     *events = lustre_ctl->difference;
00607 
00608     return PAPI_OK;
00609 
00610 }

Here is the call graph for this function:

static int _lustre_reset ( hwd_context_t ctx,
hwd_control_state_t ctrl 
) [static]

Definition at line 619 of file linux-lustre.c.

00620 {
00621 
00622   /* re-initializes counter_start values to current */
00623 
00624   _lustre_start(ctx,ctrl);
00625 
00626   return PAPI_OK;
00627 }

Here is the call graph for this function:

static int _lustre_set_domain ( hwd_control_state_t cntrl,
int  domain 
) [static]

Definition at line 675 of file linux-lustre.c.

00676 {
00677     ( void ) cntrl;
00678     ( void ) domain;
00679     SUBDBG("ENTER: \n");
00680 
00681     // this component does not allow limiting which domains will increment event counts
00682 
00683     SUBDBG("EXIT: PAPI_OK\n");
00684     return PAPI_OK;
00685 }

static int _lustre_shutdown_component ( void   )  [static]

Definition at line 468 of file linux-lustre.c.

00469 {
00470     SUBDBG("ENTER:\n");
00471     host_finalize(  );
00472     papi_free( lustre_native_table );
00473     lustre_native_table = NULL;
00474     num_events = 0;
00475         table_size = 32;
00476     SUBDBG("EXIT:\n");
00477     return PAPI_OK;
00478 }

Here is the call graph for this function:

static int _lustre_shutdown_thread ( hwd_context_t ctx  )  [static]

Definition at line 484 of file linux-lustre.c.

00485 {
00486     ( void ) ctx;
00487 
00488     return PAPI_OK;
00489 }

static int _lustre_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 538 of file linux-lustre.c.

00539 {
00540     ( void ) ctx;
00541 
00542     LUSTRE_control_state_t *lustre_ctl = (LUSTRE_control_state_t *)ctl;
00543     int i;
00544 
00545     read_lustre_counter(  );
00546 
00547     for(i=0;i<lustre_ctl->num_events;i++) {
00548        lustre_ctl->current_count[i]=
00549                  lustre_native_table[lustre_ctl->which_counter[i]]->value;
00550     }
00551 
00552     memcpy( lustre_ctl->start_count,
00553         lustre_ctl->current_count,
00554         LUSTRE_MAX_COUNTERS * sizeof ( long long ) );
00555 
00556     return PAPI_OK;
00557 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _lustre_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 564 of file linux-lustre.c.

00565 {
00566 
00567     (void) ctx;
00568     LUSTRE_control_state_t *lustre_ctl = (LUSTRE_control_state_t *)ctl;
00569     int i;
00570 
00571     read_lustre_counter(  );
00572 
00573     for(i=0;i<lustre_ctl->num_events;i++) {
00574        lustre_ctl->current_count[i]=
00575                  lustre_native_table[lustre_ctl->which_counter[i]]->value;
00576     }
00577 
00578     return PAPI_OK;
00579 
00580 }

Here is the call graph for this function:

static int _lustre_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
) [static]

Definition at line 512 of file linux-lustre.c.

00516 {
00517    SUBDBG("ENTER: ctl: %p, native: %p, count: %d, ctx: %p\n", ctl, native, count, ctx);
00518     LUSTRE_control_state_t *lustre_ctl = (LUSTRE_control_state_t *)ctl;
00519     ( void ) ctx;
00520     int i, index;
00521 
00522     for ( i = 0; i < count; i++ ) {
00523        index = native[i].ni_event;
00524        lustre_ctl->which_counter[i]=index;
00525        native[i].ni_position = i;
00526     }
00527 
00528     lustre_ctl->num_events=count;
00529     SUBDBG("EXIT: PAPI_OK\n");
00530     return PAPI_OK;
00531 }

static counter_info* addCounter ( const char *  name,
const char *  desc,
const char *  unit 
) [static]

add a counter to the list of available counters

Parameters:
name the short name of the counter
desc a longer description
unit the unit for this counter

Definition at line 125 of file linux-lustre.c.

00126 {
00127    SUBDBG("ENTER: name: %s, desc: %s, unit: %s\n", name, desc, unit);
00128 
00129     counter_info *cntr;
00130 
00131     if ( num_events >= table_size )
00132     if (PAPI_OK != resize_native_table()) {
00133         SUBDBG("EXIT: can not resize native table\n" );
00134             return NULL;
00135     }
00136 
00137     cntr = malloc( sizeof ( counter_info ) );
00138 
00139     if ( cntr == NULL ) {
00140        SUBDBG("EXIT: can not allocate memory for new counter\n" );
00141        return NULL;
00142     }
00143 
00144     cntr->idx=num_events;
00145     cntr->name = strdup( name );
00146     cntr->description = strdup( desc );
00147     cntr->unit = strdup( unit );
00148     cntr->value = 0;
00149 
00150     lustre_native_table[num_events]=cntr;
00151 
00152     num_events++;
00153 
00154 SUBDBG("EXIT: cntr: %p\n", cntr);
00155     return cntr;
00156 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int addLustreFS ( const char *  name,
const char *  procpath_general,
const char *  procpath_readahead 
) [static]

adds a Lustre fs to the fs list and creates the counters for it

Parameters:
name fs name
procpath_general path to the 'stats' file in /proc/fs/lustre/... for this fs
procpath_readahead path to the 'readahead' file in /proc/fs/lustre/... for this fs

Definition at line 165 of file linux-lustre.c.

00168 {
00169     lustre_fs *fs, *last;
00170     char counter_name[512];
00171     FILE *fff;
00172 
00173     SUBDBG("Adding lustre fs\n");
00174 
00175     fs = malloc( sizeof ( lustre_fs ) );
00176     if ( fs == NULL ) {
00177        SUBDBG("can not allocate memory for new Lustre FS description\n" );
00178        return PAPI_ENOMEM;
00179     }
00180 
00181     fs->proc_file=strdup(procpath_general);
00182     fff = fopen( procpath_general, "r" );
00183     if ( fff == NULL ) {
00184       SUBDBG("can not open '%s'\n", procpath_general );
00185       free(fs);
00186       return PAPI_ESYS;
00187     }
00188     fclose(fff);
00189 
00190     fs->proc_file_readahead = strdup(procpath_readahead);
00191     fff = fopen( procpath_readahead, "r" );
00192     if ( fff == NULL ) {
00193       SUBDBG("can not open '%s'\n", procpath_readahead );
00194       free(fs);
00195       return PAPI_ESYS;
00196     }
00197     fclose(fff);
00198 
00199     sprintf( counter_name, "%s_llread", name );
00200     if (NULL == (fs->read_cntr = addCounter( counter_name, 
00201                     "bytes read on this lustre client", 
00202                     "bytes" ))) {
00203             free(fs);
00204             return PAPI_ENOMEM;
00205     }
00206 
00207     sprintf( counter_name, "%s_llwrite", name );
00208     if ( NULL == (fs->write_cntr = addCounter( counter_name, 
00209                      "bytes written on this lustre client",
00210                      "bytes" ))) {
00211             free(fs->read_cntr);
00212             free(fs);
00213             return PAPI_ENOMEM;
00214     }
00215 
00216     sprintf( counter_name, "%s_wrong_readahead", name );
00217     if ( NULL == (fs->readahead_cntr = addCounter( counter_name, 
00218                      "bytes read but discarded due to readahead",
00219                      "bytes" ))) {
00220             free(fs->read_cntr);
00221             free(fs->write_cntr);
00222             free(fs);
00223             return PAPI_ENOMEM;
00224     }
00225 
00226     fs->next = NULL;
00227 
00228     /* Insert into the linked list */
00229     /* Does this need locking? */
00230     if ( root_lustre_fs == NULL ) {
00231         root_lustre_fs = fs;
00232     } else {
00233         last = root_lustre_fs;
00234 
00235         while ( last->next != NULL )
00236             last = last->next;
00237 
00238         last->next = fs;
00239     }
00240     return PAPI_OK;
00241 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void host_finalize ( void   )  [static]

frees all allocated resources

Definition at line 387 of file linux-lustre.c.

00388 {
00389         int i;
00390     lustre_fs *fs, *next_fs;
00391     counter_info *cntr;
00392 
00393     for(i=0;i<num_events;i++) {
00394        cntr=lustre_native_table[i];
00395        if ( cntr != NULL ) {
00396           free( cntr->name );
00397           free( cntr->description );
00398           free( cntr->unit );
00399           free( cntr );       
00400        }
00401        lustre_native_table[i]=NULL;
00402     }
00403 
00404     fs = root_lustre_fs;
00405 
00406     while ( fs != NULL ) {
00407         next_fs = fs->next;
00408         free(fs->proc_file);
00409         free(fs->proc_file_readahead);
00410         free( fs );
00411         fs = next_fs;
00412     }
00413 
00414     root_lustre_fs = NULL;
00415 }

Here is the caller graph for this function:

static int init_lustre_counters ( void   )  [static]

goes through proc and tries to discover all mounted Lustre fs

Definition at line 248 of file linux-lustre.c.

00249 {
00250    SUBDBG("ENTER:\n");
00251         char lustre_dir[PATH_MAX];
00252     char path[PATH_MAX];
00253     char path_readahead[PATH_MAX],path_stats[PATH_MAX];
00254     char *ptr;
00255     char fs_name[100];
00256     int found_luster_fs = 0;
00257     int idx = 0;
00258     int tmp_fd;
00259     DIR *proc_dir;
00260     struct dirent *entry;
00261 
00262     sprintf(lustre_dir,"%s/llite",proc_base_path);
00263 
00264     proc_dir = opendir( lustre_dir );
00265     if ( proc_dir == NULL ) {
00266       SUBDBG("EXIT: PAPI_ESYS (Cannot open %s)\n",lustre_dir);
00267        return PAPI_ESYS;
00268     }
00269 
00270    while ( (entry = readdir( proc_dir )) != NULL ) {
00271        memset( path, 0, PATH_MAX );
00272        snprintf( path, PATH_MAX - 1, "%s/%s/stats", lustre_dir,
00273                   entry->d_name );
00274        SUBDBG("checking for file %s\n", path);
00275 
00276        if ( ( tmp_fd = open( path, O_RDONLY ) ) == -1 ) {
00277            SUBDBG("Path: %s, can not be opened.\n", path);
00278            continue;
00279        }
00280 
00281       close( tmp_fd );
00282 
00283       /* erase \r and \n at the end of path */
00284       /* why is this necessary?             */
00285 
00286       idx = strlen( path );
00287       idx--;
00288 
00289       while ( path[idx] == '\r' || path[idx] == '\n' )
00290         path[idx--] = 0;
00291 
00292       /* Lustre paths are of type server-UUID */
00293 
00294       idx = 0;
00295 
00296       ptr = strstr(path,"llite/") + 6;
00297      if (ptr == NULL) {
00298       SUBDBG("Path: %s, missing llite directory, performance event not created.\n", path);
00299       continue;
00300       }
00301 
00302      strncpy(fs_name, ptr, sizeof(fs_name)-1);
00303      fs_name[sizeof(fs_name)-1] = '\0';
00304 
00305       SUBDBG("found Lustre FS: %s\n", fs_name);
00306 
00307       snprintf( path_stats, PATH_MAX - 1,
00308         "%s/%s/stats",
00309         lustre_dir,
00310         entry->d_name );
00311       SUBDBG("Found file %s\n", path_stats);
00312 
00313       snprintf( path_readahead, PATH_MAX - 1,
00314         "%s/%s/read_ahead_stats",
00315         lustre_dir,
00316         entry->d_name );
00317       SUBDBG("Now checking for file %s\n", path_readahead);
00318 
00319       strcpy( ptr, "read_ahead_stats" );
00320       addLustreFS( fs_name, path_stats, path_readahead );
00321       found_luster_fs++;
00322     }
00323     closedir( proc_dir );
00324 
00325     if (found_luster_fs == 0) {
00326         SUBDBG("EXIT: PAPI_ESYS (No luster file systems found)\n");
00327         return PAPI_ESYS;
00328     }
00329 
00330    SUBDBG("EXIT: PAPI_OK\n");
00331     return PAPI_OK;
00332 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void read_lustre_counter (  )  [static]

updates all Lustre related counters

Definition at line 338 of file linux-lustre.c.

00339 {
00340     lustre_fs *fs = root_lustre_fs;
00341     FILE *fff;
00342     char buffer[BUFSIZ];
00343 
00344     while ( fs != NULL ) {
00345 
00346       /* read values from stats file */
00347       fff=fopen(fs->proc_file,"r" );
00348       if (fff != NULL) {
00349           while(1) {
00350             if (fgets(buffer,BUFSIZ,fff)==NULL) break;
00351     
00352             if (strstr( buffer, "write_bytes" )) {
00353               sscanf(buffer,"%*s %*d %*s %*s %*d %*d %llu",&fs->write_cntr->value);
00354               SUBDBG("Read %llu write_bytes\n",fs->write_cntr->value);
00355             }
00356     
00357             if (strstr( buffer, "read_bytes" )) {
00358               sscanf(buffer,"%*s %*d %*s %*s %*d %*d %llu",&fs->read_cntr->value);
00359               SUBDBG("Read %llu read_bytes\n",fs->read_cntr->value);
00360             }
00361           }
00362           fclose(fff);
00363       }
00364 
00365       fff=fopen(fs->proc_file_readahead,"r");
00366       if (fff != NULL) {
00367           while(1) {
00368             if (fgets(buffer,BUFSIZ,fff)==NULL) break;
00369     
00370             if (strstr( buffer, "read but discarded")) {
00371                sscanf(buffer,"%*s %*s %*s %llu",&fs->readahead_cntr->value);
00372                SUBDBG("Read %llu discared\n",fs->readahead_cntr->value);
00373                break;
00374             }
00375           }
00376           fclose(fff);
00377       }
00378       fs = fs->next;
00379     }
00380 }

Here is the caller graph for this function:

static int resize_native_table (  )  [static]

Definition at line 99 of file linux-lustre.c.

00099                                  {
00100     SUBDBG("ENTER:\n");
00101     counter_info** new_table;
00102     int new_size = table_size*2;
00103     new_table = (counter_info**)papi_calloc(sizeof(counter_info*), new_size);
00104     if (NULL==new_table) {
00105         SUBDBG("EXIT: PAPI_ENOMEM\n");
00106         return PAPI_ENOMEM;
00107     }
00108     if ( lustre_native_table) {
00109         memcpy(new_table, lustre_native_table, sizeof(counter_info*) * table_size );
00110         papi_free(lustre_native_table);
00111     }
00112     lustre_native_table = new_table;
00113     table_size*=2;
00114     SUBDBG("EXIT: PAPI_OK\n");
00115     return PAPI_OK;
00116 }

Here is the caller graph for this function:


Variable Documentation

Definition at line 94 of file linux-lustre.c.

counter_info** lustre_native_table = NULL [static]

Definition at line 87 of file linux-lustre.c.

int num_events = 0 [static]

Definition at line 88 of file linux-lustre.c.

const char proc_base_path[] = "/proc/fs/lustre/"

Definition at line 84 of file linux-lustre.c.

lustre_fs* root_lustre_fs = NULL [static]

Definition at line 92 of file linux-lustre.c.

int table_size = 32 [static]

Definition at line 89 of file linux-lustre.c.


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1