cache the dirname => device lookups
This commit is contained in:
		
							parent
							
								
									b601f3b32d
								
							
						
					
					
						commit
						d7adfbd94a
					
				@ -8,8 +8,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "sigar.h"
 | 
					#include "sigar.h"
 | 
				
			||||||
#include "sigar_private.h"
 | 
					#include "sigar_private.h"
 | 
				
			||||||
#include "sigar_os.h"
 | 
					 | 
				
			||||||
#include "sigar_util.h"
 | 
					#include "sigar_util.h"
 | 
				
			||||||
 | 
					#include "sigar_os.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/page.h> /* for PAGE_SHIFT */
 | 
					#include <asm/page.h> /* for PAGE_SHIFT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -139,11 +139,16 @@ int sigar_os_open(sigar_t **sigar)
 | 
				
			|||||||
        (*sigar)->iostat = IOSTAT_NONE;
 | 
					        (*sigar)->iostat = IOSTAT_NONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*sigar)->fsdev = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return SIGAR_OK;
 | 
					    return SIGAR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int sigar_os_close(sigar_t *sigar)
 | 
					int sigar_os_close(sigar_t *sigar)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if (sigar->fsdev) {
 | 
				
			||||||
 | 
					        sigar_cache_destroy(sigar->fsdev);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    free(sigar);
 | 
					    free(sigar);
 | 
				
			||||||
    return SIGAR_OK;
 | 
					    return SIGAR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1011,42 +1016,89 @@ int sigar_file_system_list_get(sigar_t *sigar,
 | 
				
			|||||||
    return SIGAR_OK;
 | 
					    return SIGAR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FSDEV_NONE "__NONE__"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FSDEV_ID(sb) (sb.st_ino + sb.st_dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void fsdev_free(void *ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (ptr != FSDEV_NONE) {
 | 
				
			||||||
 | 
					        free(ptr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *get_fsdev(sigar_t *sigar,
 | 
					static char *get_fsdev(sigar_t *sigar,
 | 
				
			||||||
                       const char *dirname,
 | 
					                       const char *dirname,
 | 
				
			||||||
                       char *fsdev)
 | 
					                       char *fsdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* XXX cache this shit */
 | 
					    sigar_cache_entry_t *entry;
 | 
				
			||||||
    struct mntent ent;
 | 
					    struct stat sb;
 | 
				
			||||||
    char buf[1025]; /* buffer for strings within ent */
 | 
					    sigar_uint64_t id;
 | 
				
			||||||
    FILE *fp;
 | 
					 | 
				
			||||||
    char *ptr = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(fp = setmntent(MOUNTED, "r"))) {
 | 
					    if (stat(dirname, &sb) < 0) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (getmntent_r(fp, &ent, buf, sizeof(buf))) {
 | 
					    id = FSDEV_ID(sb);
 | 
				
			||||||
        if (strEQ(ent.mnt_dir, dirname)) {
 | 
					
 | 
				
			||||||
            ptr = ent.mnt_fsname;
 | 
					    if (!sigar->fsdev) {
 | 
				
			||||||
            break;
 | 
					        sigar->fsdev = sigar_cache_new(15);
 | 
				
			||||||
 | 
					        sigar->fsdev->free_value = fsdev_free;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry = sigar_cache_get(sigar->fsdev, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (entry->value == NULL) {
 | 
				
			||||||
 | 
					        sigar_file_system_list_t fslist;
 | 
				
			||||||
 | 
					        int status = sigar_file_system_list_get(sigar, &fslist);
 | 
				
			||||||
 | 
					        int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (status != SIGAR_OK) {
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i=0; i<fslist.number; i++) {
 | 
				
			||||||
 | 
					            sigar_file_system_t *fsp = &fslist.data[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) {
 | 
				
			||||||
 | 
					                int retval = stat(fsp->dir_name, &sb);
 | 
				
			||||||
 | 
					                sigar_cache_entry_t *ent;
 | 
				
			||||||
 | 
					                char *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (retval < 0) {
 | 
				
			||||||
 | 
					                    return NULL; /* cant cache w/o inode */
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ent = sigar_cache_get(sigar->fsdev, FSDEV_ID(sb));
 | 
				
			||||||
 | 
					                if (ent->value) {
 | 
				
			||||||
 | 
					                    continue; /* already cached */
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ptr = fsp->dev_name;
 | 
				
			||||||
 | 
					                if (strnEQ(ptr, "/dev/", 5)) {
 | 
				
			||||||
 | 
					                    ptr += 5;
 | 
				
			||||||
 | 
					                    ent->value = strdup(ptr);
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ent->value = FSDEV_NONE;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sigar_file_system_list_destroy(sigar, &fslist);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    endmntent(fp);
 | 
					    if (entry->value == FSDEV_NONE) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!ptr) {
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else if (entry->value == NULL) {
 | 
				
			||||||
    if (!strnEQ(ptr, "/dev/", 5)) {
 | 
					        entry->value = FSDEV_NONE;
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
    ptr += 5;
 | 
					        strcpy(fsdev, (char*)entry->value);
 | 
				
			||||||
 | 
					        return fsdev;
 | 
				
			||||||
    strcpy(fsdev, ptr);
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return ptr;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int get_iostat_sys(sigar_t *sigar,
 | 
					static int get_iostat_sys(sigar_t *sigar,
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,7 @@ struct sigar_t {
 | 
				
			|||||||
    int ht_enabled;
 | 
					    int ht_enabled;
 | 
				
			||||||
    int lcpu;
 | 
					    int lcpu;
 | 
				
			||||||
    linux_iostat_e iostat;
 | 
					    linux_iostat_e iostat;
 | 
				
			||||||
 | 
					    sigar_cache_t *fsdev;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HAVE_STRERROR_R
 | 
					#define HAVE_STRERROR_R
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user