diff --git a/src/pmdas/linux/clusters.h b/src/pmdas/linux/clusters.h index a33f41b..ff29bf3 100644 --- a/src/pmdas/linux/clusters.h +++ b/src/pmdas/linux/clusters.h @@ -57,6 +57,7 @@ enum { CLUSTER_PID_SCHEDSTAT, /* 31 /proc//schedstat */ CLUSTER_PID_IO, /* 32 /proc//io */ CLUSTER_NET_INET, /* 33 /proc/net/dev and ioctl(SIOCGIFCONF) */ + CLUSTER_TMPFS, /* 34 /proc/mounts + statfs (tmpfs only) */ NUM_CLUSTERS /* one more than highest numbered cluster */ }; diff --git a/src/pmdas/linux/filesys.c b/src/pmdas/linux/filesys.c index e701be0..90fc00f 100644 --- a/src/pmdas/linux/filesys.c +++ b/src/pmdas/linux/filesys.c @@ -101,11 +101,12 @@ next: } int -refresh_filesys(pmInDom filesys_indom, pmInDom quota_indom) +refresh_filesys(pmInDom filesys_indom, pmInDom quota_indom, pmInDom tmpfs_indom) { char buf[MAXPATHLEN]; char realdevice[MAXPATHLEN]; filesys_t *fs; + pmInDom indom; FILE *fp; char *path; char *device; @@ -113,17 +114,15 @@ refresh_filesys(pmInDom filesys_indom, pmInDom quota_indom) int sts; pmdaCacheOp(quota_indom, PMDA_CACHE_INACTIVE); + pmdaCacheOp(tmpfs_indom, PMDA_CACHE_INACTIVE); pmdaCacheOp(filesys_indom, PMDA_CACHE_INACTIVE); if ((fp = fopen("/proc/mounts", "r")) == (FILE *)NULL) return -errno; while (fgets(buf, sizeof(buf), fp) != NULL) { - if (( device = strtok(buf, " ")) == 0 - || strncmp(device, "/dev", 4) != 0) + if ((device = strtok(buf, " ")) == 0) continue; - if (realpath(device, realdevice) != NULL) - device = realdevice; path = strtok(NULL, " "); type = strtok(NULL, " "); @@ -134,11 +133,21 @@ refresh_filesys(pmInDom filesys_indom, pmInDom quota_indom) strncmp(type, "auto", 4) == 0) continue; - sts = pmdaCacheLookupName(filesys_indom, device, NULL, (void **)&fs); + indom = filesys_indom; + if (strcmp(type, "tmpfs") == 0) { + indom = tmpfs_indom; + device = path; + } + else if (strncmp(device, "/dev", 4) != 0) + continue; + if (realpath(device, realdevice) != NULL) + device = realdevice; + + sts = pmdaCacheLookupName(indom, device, NULL, (void **)&fs); if (sts == PMDA_CACHE_ACTIVE) /* repeated line in /proc/mounts? */ continue; if (sts == PMDA_CACHE_INACTIVE) { /* re-activate an old mount */ - pmdaCacheStore(filesys_indom, PMDA_CACHE_ADD, device, fs); + pmdaCacheStore(indom, PMDA_CACHE_ADD, device, fs); if (strcmp(path, fs->path) != 0) { /* old device, new path */ free(fs->path); fs->path = strdup(path); @@ -155,7 +164,7 @@ refresh_filesys(pmInDom filesys_indom, pmInDom quota_indom) fs->path, device); } #endif - pmdaCacheStore(filesys_indom, PMDA_CACHE_ADD, device, fs); + pmdaCacheStore(indom, PMDA_CACHE_ADD, device, fs); } fs->flags = 0; diff --git a/src/pmdas/linux/filesys.h b/src/pmdas/linux/filesys.h index 2425fc5..568c28a 100644 --- a/src/pmdas/linux/filesys.h +++ b/src/pmdas/linux/filesys.h @@ -106,4 +106,4 @@ typedef struct filesys { struct statfs stats; } filesys_t; -extern int refresh_filesys(pmInDom, pmInDom); +extern int refresh_filesys(pmInDom, pmInDom, pmInDom); diff --git a/src/pmdas/linux/help b/src/pmdas/linux/help index 95f15d9..f429ae9 100644 --- a/src/pmdas/linux/help +++ b/src/pmdas/linux/help @@ -638,10 +638,17 @@ are SCSI tapes and scd[0-9] are SCSI CD-ROMS. @ filesys.maxfiles Inodes capacity of mounted filesystem @ filesys.usedfiles Number of inodes allocated on mounted filesystem @ filesys.freefiles Number of unallocated inodes on mounted filesystem -@ filesys.mountdir file system mount point -@ filesys.full percentage of filesystem in use +@ filesys.mountdir File system mount point +@ filesys.full Percentage of filesystem in use @ filesys.blocksize Size of each block on mounted filesystem (Bytes) @ filesys.avail Total space free to non-superusers on mounted filesystem (Kbytes) +@ tmpfs.capacity Total capacity of mounted tmpfs filesystem (Kbytes) +@ tmpfs.used Total space used on mounted tmpfs filesystem (Kbytes) +@ tmpfs.free Total space free on mounted tmpfs filesystem (Kbytes) +@ tmpfs.maxfiles Inodes capacity of mounted tmpfs filesystem +@ tmpfs.usedfiles Number of inodes allocated on mounted tmpfs filesystem +@ tmpfs.freefiles Number of unallocated inodes on mounted tmpfs filesystem +@ tmpfs.full Percentage of tmpfs filesystem in use @ swapdev.free physical swap free space @ swapdev.length physical swap size @ swapdev.maxswap maximum swap length (same as swapdev.length on Linux) diff --git a/src/pmdas/linux/indom.h b/src/pmdas/linux/indom.h index 36b1f72..bfd3dbb 100644 --- a/src/pmdas/linux/indom.h +++ b/src/pmdas/linux/indom.h @@ -37,6 +37,7 @@ #define NFS4_SVR_INDOM 15 #define QUOTA_PRJ_INDOM 16 #define NET_INET_INDOM 17 +#define TMPFS_INDOM 18 #define INDOM(x) (indomtab[x].it_indom) extern pmdaIndom indomtab[]; diff --git a/src/pmdas/linux/pmda.c b/src/pmdas/linux/pmda.c index 20789f6..f5da0c7 100644 --- a/src/pmdas/linux/pmda.c +++ b/src/pmdas/linux/pmda.c @@ -255,6 +255,7 @@ pmdaIndom indomtab[] = { { NFS4_SVR_INDOM, NR_RPC4_SVR_COUNTERS, nfs4_svr_indom_id }, { QUOTA_PRJ_INDOM, 0, NULL }, { NET_INET_INDOM, 0, NULL }, + { TMPFS_INDOM, 0, NULL }, }; @@ -1018,6 +1019,45 @@ static pmdaMetric metrictab[] = { PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}}, /* + * tmpfs filesystem cluster + */ + +/* tmpfs.capacity */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,1), PM_TYPE_U64, TMPFS_INDOM, PM_SEM_DISCRETE, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } }, + +/* tmpfs.used */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,2), PM_TYPE_U64, TMPFS_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } }, + +/* tmpfs.free */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,3), PM_TYPE_U64, TMPFS_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } }, + +/* tmpfs.maxfiles */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,4), PM_TYPE_U32, TMPFS_INDOM, PM_SEM_DISCRETE, + PMDA_PMUNITS(0,0,0,0,0,0) } }, + +/* tmpfs.usedfiles */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,5), PM_TYPE_U32, TMPFS_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(0,0,0,0,0,0) } }, + +/* tmpfs.freefiles */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,6), PM_TYPE_U32, TMPFS_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(0,0,0,0,0,0) } }, + +/* tmpfs.full */ + { NULL, + { PMDA_PMID(CLUSTER_TMPFS,7), PM_TYPE_DOUBLE, TMPFS_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(0,0,0,0,0,0) } }, + +/* * swapdev cluster */ @@ -3375,8 +3415,10 @@ linux_refresh(int *need_refresh) if (need_refresh[CLUSTER_NET_INET]) refresh_net_dev_inet(INDOM(NET_INET_INDOM)); - if (need_refresh[CLUSTER_FILESYS] || need_refresh[CLUSTER_QUOTA]) - refresh_filesys(INDOM(FILESYS_INDOM), INDOM(QUOTA_PRJ_INDOM)); + if (need_refresh[CLUSTER_FILESYS] || need_refresh[CLUSTER_QUOTA] || + need_refresh[CLUSTER_TMPFS]) + refresh_filesys(INDOM(FILESYS_INDOM), INDOM(QUOTA_PRJ_INDOM), + INDOM(TMPFS_INDOM)); if (need_refresh[CLUSTER_SWAPDEV]) refresh_swapdev(INDOM(SWAPDEV_INDOM)); @@ -3460,6 +3502,9 @@ linux_instance(pmInDom indom, int inst, char *name, __pmInResult **result, pmdaE case FILESYS_INDOM: need_refresh[CLUSTER_FILESYS]++; break; + case TMPFS_INDOM: + need_refresh[CLUSTER_TMPFS]++; + break; case QUOTA_PRJ_INDOM: need_refresh[CLUSTER_QUOTA]++; break; @@ -4196,6 +4241,57 @@ linux_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom) } break; + case CLUSTER_TMPFS: { + struct statfs *sbuf; + struct filesys *fs; + __uint64_t ull, used; + + sts = pmdaCacheLookup(INDOM(TMPFS_INDOM), inst, NULL, (void **)&fs); + if (sts < 0) + return sts; + if (sts != PMDA_CACHE_ACTIVE) + return PM_ERR_INST; + + sbuf = &fs->stats; + if (!(fs->flags & FSF_FETCHED)) { + if (statfs(fs->path, sbuf) < 0) + return -errno; + fs->flags |= FSF_FETCHED; + } + + switch (idp->item) { + case 1: /* tmpfs.capacity */ + ull = (__uint64_t)sbuf->f_blocks; + atom->ull = ull * sbuf->f_bsize / 1024; + break; + case 2: /* tmpfs.used */ + used = (__uint64_t)(sbuf->f_blocks - sbuf->f_bfree); + atom->ull = used * sbuf->f_bsize / 1024; + break; + case 3: /* tmpfs.free */ + ull = (__uint64_t)sbuf->f_bfree; + atom->ull = ull * sbuf->f_bsize / 1024; + break; + case 4: /* tmpfs.maxfiles */ + atom->ul = sbuf->f_files; + break; + case 5: /* tmpfs.usedfiles */ + atom->ul = sbuf->f_files - sbuf->f_ffree; + break; + case 6: /* tmpfs.freefiles */ + atom->ul = sbuf->f_ffree; + break; + case 7: /* tmpfs.full */ + used = (__uint64_t)(sbuf->f_blocks - sbuf->f_bfree); + ull = used + (__uint64_t)sbuf->f_bavail; + atom->d = (100.0 * (double)used) / (double)ull; + break; + default: + return PM_ERR_PMID; + } + } + break; + case CLUSTER_SWAPDEV: { struct swapdev *swap; diff --git a/src/pmdas/linux/root_linux b/src/pmdas/linux/root_linux index 3f037d0..1ccc04b 100644 --- a/src/pmdas/linux/root_linux +++ b/src/pmdas/linux/root_linux @@ -33,6 +33,7 @@ root { ipc vfs quota + tmpfs } hinv { @@ -461,6 +462,16 @@ filesys { avail 60:5:10 } +tmpfs { + capacity 60:34:1 + used 60:34:2 + free 60:34:3 + maxfiles 60:34:4 + usedfiles 60:34:5 + freefiles 60:34:6 + full 60:34:7 +} + swapdev { free 60:6:0 length 60:6:1