#include #include #include #include #include #include #include #include #include "procps-private.h" #define VMSTAT_FILE "/proc/vmstat" #define ROW_NAME_LEN 32 struct vmstat_data { unsigned long pgpgin; unsigned long pgpgout; unsigned long pswpin; unsigned long pswpout; }; struct mem_table_struct { const char *name; unsigned long *slot; }; struct vmstat_info { int refcount; int vmstat_fd; struct vmstat_data data; }; /* * procps_vmstat_new: * * Create a new container to hold the vmstat information * * The initial refcount is 1, and needs to be decremented * to release the resources of the structure. * * Returns: a new vmstat info container */ PROCPS_EXPORT int procps_vmstat_new(struct vmstat_info **info) { struct vmstat_info *v; v = calloc(1, sizeof(struct vmstat_info)); if (!v) return -ENOMEM; v->refcount = 1; v->vmstat_fd = -1; *info = v; return 0; } /* * procps_vmstat_read: * * Read the data out of /proc/vmstat putting the information * into the supplied info structure */ PROCPS_EXPORT int procps_vmstat_read(struct vmstat_info *info) { char buf[8192]; char *head, *tail; int size; unsigned long *valptr; if (info == NULL) return -1; memset(&(info->data), 0, sizeof(struct vmstat_data)); /* read in the data */ if (-1 == info->vmstat_fd && (info->vmstat_fd = open(VMSTAT_FILE, O_RDONLY)) == -1) { return -errno; } if (lseek(info->vmstat_fd, 0L, SEEK_SET) == -1) { return -errno; } if ((size = read(info->vmstat_fd, buf, sizeof(buf)-1)) < 0) { return -1; } buf[size] = '\0'; /* Scan the file */ head = buf; do { tail = strchr(head, ' '); if (!tail) break; *tail = '\0'; valptr = NULL; if (0 == strcmp(head, "pgpgin")) { valptr = &(info->data.pgpgin); }else if (0 == strcmp(head, "pgpgout")) { valptr = &(info->data.pgpgout); }else if (0 == strcmp(head, "pswpin")) { valptr = &(info->data.pswpin); }else if (0 == strcmp(head, "pswpout")) { valptr = &(info->data.pswpout); } head = tail+1; if (valptr) { *valptr = strtoul(head, &tail, 10); } tail = strchr(head, '\n'); if (!tail) break; head = tail + 1; } while(tail); return 0; } PROCPS_EXPORT struct vmstat_info *procps_vmstat_ref(struct vmstat_info *info) { if (info == NULL) return NULL; info->refcount++; return info; } PROCPS_EXPORT struct vmstat_info *procps_vmstat_unref(struct vmstat_info *info) { if (info == NULL) return NULL; info->refcount--; if (info->refcount > 0) return NULL; free(info); return NULL; } /* Accessor functions */ PROCPS_EXPORT unsigned long procps_vmstat_get( struct vmstat_info *info, enum vmstat_item item) { switch(item) { case VMSTAT_INFO_PGPGIN: return info->data.pgpgin; case VMSTAT_INFO_PGPGOUT: return info->data.pgpgout; case VMSTAT_INFO_PSWPIN: return info->data.pswpin; case VMSTAT_INFO_PSWPOUT: return info->data.pswpout; } return 0; }