mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-16 18:15:17 +00:00
Integrate FreeBSD diskio support.
This diff moves Linux-specific parts of diskio.c into linux.c and uses the remaining diskio functions to correctly implement this functionality for FreeBSD. It also hooks diskio.c to the FreeBSD build. Signed-off-by: Brenden Matthews <brenden@rty.ca>
This commit is contained in:
parent
ec2597f944
commit
12d0d1477f
@ -77,7 +77,7 @@ endif
|
||||
#endif
|
||||
|
||||
if BUILD_FREEBSD
|
||||
freebsd = freebsd.c
|
||||
freebsd = freebsd.c diskio.c
|
||||
PTHREAD_LIBS = -pthread
|
||||
endif
|
||||
|
||||
|
96
src/diskio.c
96
src/diskio.c
@ -33,24 +33,11 @@
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
/* The following ifdefs were adapted from gkrellm */
|
||||
#include <linux/major.h>
|
||||
|
||||
#if !defined(MD_MAJOR)
|
||||
#define MD_MAJOR 9
|
||||
#endif
|
||||
|
||||
#if !defined(LVM_BLK_MAJOR)
|
||||
#define LVM_BLK_MAJOR 58
|
||||
#endif
|
||||
|
||||
#if !defined(NBD_MAJOR)
|
||||
#define NBD_MAJOR 43
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* this is the root of all per disk stats,
|
||||
* also containing the totals. */
|
||||
static struct diskio_stat stats = {
|
||||
struct diskio_stat stats = {
|
||||
.next = NULL,
|
||||
.sample = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
.sample_read = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
@ -75,30 +62,48 @@ void clear_diskio_stats(void)
|
||||
|
||||
struct diskio_stat *prepare_diskio_stat(const char *s)
|
||||
{
|
||||
struct stat sb;
|
||||
char stat_name[text_buffer_size], device_name[text_buffer_size];
|
||||
struct diskio_stat *cur = &stats;
|
||||
|
||||
if (!s)
|
||||
return &stats;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
if (strncmp(s, "/dev/", 5) == 0) {
|
||||
// supplied a /dev/device arg, so cut off the /dev part
|
||||
strncpy(device_name, s + 5, text_buffer_size);
|
||||
} else
|
||||
#endif
|
||||
strncpy(device_name, s, text_buffer_size);
|
||||
|
||||
snprintf(stat_name, text_buffer_size, "/dev/%s", device_name);
|
||||
|
||||
if (stat(stat_name, &sb)) {
|
||||
ERR("diskio device '%s' does not exist", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lookup existing */
|
||||
while (cur->next) {
|
||||
cur = cur->next;
|
||||
if (!strcmp(cur->dev, s))
|
||||
if (!strcmp(cur->dev, device_name)) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
|
||||
/* no existing found, make a new one */
|
||||
cur->next = malloc(sizeof(struct diskio_stat));
|
||||
cur->next = calloc(1, sizeof(struct diskio_stat));
|
||||
cur = cur->next;
|
||||
memset(cur, 0, sizeof(struct diskio_stat));
|
||||
cur->dev = strndup(s, text_buffer_size);
|
||||
cur->dev = strndup(device_name, text_buffer_size);
|
||||
cur->last = UINT_MAX;
|
||||
cur->last_read = UINT_MAX;
|
||||
cur->last_write = UINT_MAX;
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
static void update_diskio_values(struct diskio_stat *ds,
|
||||
void update_diskio_values(struct diskio_stat *ds,
|
||||
unsigned int reads, unsigned int writes)
|
||||
{
|
||||
int i;
|
||||
@ -140,54 +145,3 @@ static void update_diskio_values(struct diskio_stat *ds,
|
||||
ds->last = ds->last_read + ds->last_write;
|
||||
}
|
||||
|
||||
void update_diskio(void)
|
||||
{
|
||||
FILE *fp;
|
||||
static int rep = 0;
|
||||
|
||||
struct diskio_stat *cur;
|
||||
char buf[512], devbuf[64];
|
||||
unsigned int major, minor;
|
||||
unsigned int reads, writes;
|
||||
unsigned int total_reads=0, total_writes=0;
|
||||
int col_count = 0;
|
||||
|
||||
stats.current = 0;
|
||||
stats.current_read = 0;
|
||||
stats.current_write = 0;
|
||||
|
||||
if (!(fp = open_file("/proc/diskstats", &rep))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* read reads and writes from all disks (minor = 0), including cd-roms
|
||||
* and floppies, and sum them up */
|
||||
while (fgets(buf, 512, fp)) {
|
||||
col_count = sscanf(buf, "%u %u %s %*u %*u %u %*u %*u %*u %u", &major,
|
||||
&minor, devbuf, &reads, &writes);
|
||||
/* ignore subdevices (they have only 3 matching entries in their line)
|
||||
* and virtual devices (LVM, network block devices, RAM disks, Loopback)
|
||||
*
|
||||
* XXX: ignore devices which are part of a SW RAID (MD_MAJOR) */
|
||||
if (col_count == 5 && major != LVM_BLK_MAJOR && major != NBD_MAJOR
|
||||
&& major != RAMDISK_MAJOR && major != LOOP_MAJOR && minor==0) {
|
||||
total_reads += reads;
|
||||
total_writes += writes;
|
||||
} else {
|
||||
col_count = sscanf(buf, "%u %u %s %*u %u %*u %u",
|
||||
&major, &minor, devbuf, &reads, &writes);
|
||||
if (col_count != 5) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cur = stats.next;
|
||||
while (cur && strcmp(devbuf, cur->dev))
|
||||
cur = cur->next;
|
||||
|
||||
if (cur)
|
||||
update_diskio_values(cur, reads, writes);
|
||||
}
|
||||
update_diskio_values(&stats, total_reads, total_writes);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,11 @@ struct diskio_stat {
|
||||
double last_write;
|
||||
};
|
||||
|
||||
struct diskio_stat *prepare_diskio_stat(const char *s);
|
||||
extern struct diskio_stat stats;
|
||||
|
||||
struct diskio_stat *prepare_diskio_stat(const char *);
|
||||
void update_diskio(void);
|
||||
void clear_diskio_stats(void);
|
||||
void update_diskio_values(struct diskio_stat *, unsigned int, unsigned int);
|
||||
|
||||
#endif /* DISKIO_H_ */
|
||||
|
109
src/freebsd.c
109
src/freebsd.c
@ -65,15 +65,6 @@
|
||||
inline void proc_find_top(struct process **cpu, struct process **mem);
|
||||
|
||||
static short cpu_setup = 0;
|
||||
static struct diskio_stat stats = {
|
||||
.next = NULL,
|
||||
.current = 0,
|
||||
.current_read = 0,
|
||||
.current_write = 0,
|
||||
.last = UINT_MAX,
|
||||
.last_read = UINT_MAX,
|
||||
.last_write = UINT_MAX,
|
||||
};
|
||||
|
||||
static int getsysctl(char *name, void *ptr, size_t len)
|
||||
{
|
||||
@ -658,59 +649,49 @@ cleanup:
|
||||
|
||||
void update_diskio()
|
||||
{
|
||||
int devs_count, num_selected, num_selections;
|
||||
int devs_count, num_selected, num_selections, dn;
|
||||
struct device_selection *dev_select = NULL;
|
||||
long select_generation;
|
||||
int dn;
|
||||
static struct statinfo statinfo_cur;
|
||||
char device_name[text_buffer_size];
|
||||
struct diskio_stat *cur;
|
||||
unsigned int reads, writes;
|
||||
unsigned int total_reads = 0, total_writes = 0;
|
||||
|
||||
bzero(&statinfo_cur, sizeof(statinfo_cur));
|
||||
|
||||
memset(&statinfo_cur, 0, sizeof(statinfo_cur));
|
||||
statinfo_cur.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo));
|
||||
stats.current = stats.current_read = stats.current_write = 0;
|
||||
|
||||
if (devstat_getdevs(NULL, &statinfo_cur) < 0)
|
||||
if (devstat_getdevs(NULL, &statinfo_cur) < 0) {
|
||||
free(statinfo_cur.dinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
devs_count = statinfo_cur.dinfo->numdevs;
|
||||
if (devstat_selectdevs(&dev_select, &num_selected, &num_selections,
|
||||
&select_generation, statinfo_cur.dinfo->generation,
|
||||
statinfo_cur.dinfo->devices, devs_count, NULL, 0, NULL, 0,
|
||||
DS_SELECT_ONLY, MAXSHOWDEVS, 1) >= 0) {
|
||||
for (dn = 0; dn < devs_count; ++dn) {
|
||||
for (dn = 0; dn < devs_count; dn++) {
|
||||
int di;
|
||||
struct devstat *dev;
|
||||
|
||||
di = dev_select[dn].position;
|
||||
dev = &statinfo_cur.dinfo->devices[di];
|
||||
snprintf(device_name, text_buffer_size, "%s%d",
|
||||
dev_select[dn].device_name, dev_select[dn].unit_number);
|
||||
|
||||
total_reads += (reads = dev->bytes[DEVSTAT_READ] / 512);
|
||||
total_writes += (writes = dev->bytes[DEVSTAT_WRITE] / 512);
|
||||
for (cur = stats.next; cur; cur = cur->next) {
|
||||
if (cur->dev && !strcmp(dev_select[dn].device_name, cur->dev)) {
|
||||
cur->current = (dev->bytes[DEVSTAT_READ] +
|
||||
dev->bytes[DEVSTAT_WRITE] - cur->last) / 1024;
|
||||
cur->current_read = (dev->bytes[DEVSTAT_READ] -
|
||||
cur->last_read) / 1024;
|
||||
cur->current_write = (dev->bytes[DEVSTAT_WRITE] -
|
||||
cur->last_write) / 1024;
|
||||
if (dev->bytes[DEVSTAT_READ] + dev->bytes[DEVSTAT_WRITE] <
|
||||
cur->last) {
|
||||
cur->current = 0;
|
||||
}
|
||||
if (dev->bytes[DEVSTAT_READ] < cur->last_read) {
|
||||
cur->current_read = 0;
|
||||
cur->current = cur->current_write;
|
||||
}
|
||||
if (dev->bytes[DEVSTAT_WRITE] < cur->last_write) {
|
||||
cur->current_write = 0;
|
||||
cur->current = cur->current_read;
|
||||
}
|
||||
cur->last = dev->bytes[DEVSTAT_READ] +
|
||||
dev->bytes[DEVSTAT_WRITE];
|
||||
cur->last_read = dev->bytes[DEVSTAT_READ];
|
||||
cur->last_write = dev->bytes[DEVSTAT_WRITE];
|
||||
if (cur->dev && !strcmp(device_name, cur->dev)) {
|
||||
update_diskio_values(cur, reads, writes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
update_diskio_values(&stats, total_reads, total_writes);
|
||||
|
||||
free(dev_select);
|
||||
}
|
||||
@ -718,60 +699,6 @@ void update_diskio()
|
||||
free(statinfo_cur.dinfo);
|
||||
}
|
||||
|
||||
void clear_diskio_stats()
|
||||
{
|
||||
struct diskio_stat *cur;
|
||||
while (stats.next) {
|
||||
cur = stats.next;
|
||||
stats.next = stats.next->next;
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
struct diskio_stat *prepare_diskio_stat(const char *s)
|
||||
{
|
||||
struct diskio_stat *new = 0;
|
||||
struct stat sb;
|
||||
int found = 0;
|
||||
char device[text_buffer_size], fbuf[text_buffer_size];
|
||||
static int rep = 0;
|
||||
/* lookup existing or get new */
|
||||
struct diskio_stat *cur = &stats;
|
||||
|
||||
if (!s)
|
||||
return cur;
|
||||
|
||||
while (cur->next) {
|
||||
cur = cur->next;
|
||||
if (!strcmp(cur->dev, s))
|
||||
return cur;
|
||||
}
|
||||
|
||||
/* new dev */
|
||||
if (!(cur->next = calloc(1, sizeof(struct diskio_stat)))) {
|
||||
ERR("out of memory allocating new disk stats struct");
|
||||
return NULL;
|
||||
}
|
||||
cur = cur->next;
|
||||
cur->last = cur->last_read = cur->last_write = UINT_MAX;
|
||||
if (strncmp(s, "/dev/", 5) == 0) {
|
||||
// supplied a /dev/device arg, so cut off the /dev part
|
||||
cur->dev = strndup(s + 5, text_buffer_size);
|
||||
} else {
|
||||
cur->dev = strndup(s, text_buffer_size);
|
||||
}
|
||||
/*
|
||||
* check that device actually exists
|
||||
*/
|
||||
snprintf(device, text_buffer_size, "/dev/%s", new->dev);
|
||||
|
||||
if (stat(device, &sb)) {
|
||||
ERR("diskio device '%s' does not exist", s);
|
||||
return 0;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
/* While topless is obviously better, top is also not bad. */
|
||||
|
||||
int comparecpu(const void *a, const void *b)
|
||||
|
65
src/linux.c
65
src/linux.c
@ -30,6 +30,7 @@
|
||||
#include "logging.h"
|
||||
#include "common.h"
|
||||
#include "linux.h"
|
||||
#include "diskio.h"
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -58,6 +59,21 @@
|
||||
#include <linux/route.h>
|
||||
#include <math.h>
|
||||
|
||||
/* The following ifdefs were adapted from gkrellm */
|
||||
#include <linux/major.h>
|
||||
|
||||
#if !defined(MD_MAJOR)
|
||||
#define MD_MAJOR 9
|
||||
#endif
|
||||
|
||||
#if !defined(LVM_BLK_MAJOR)
|
||||
#define LVM_BLK_MAJOR 58
|
||||
#endif
|
||||
|
||||
#if !defined(NBD_MAJOR)
|
||||
#define NBD_MAJOR 43
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IWLIB
|
||||
#include <iwlib.h>
|
||||
#endif
|
||||
@ -2131,3 +2147,52 @@ const char *get_disk_protect_queue(const char *disk)
|
||||
return (state > 0) ? "frozen" : "free ";
|
||||
}
|
||||
|
||||
void update_diskio(void)
|
||||
{
|
||||
FILE *fp;
|
||||
static int rep = 0;
|
||||
char buf[512], devbuf[64];
|
||||
unsigned int major, minor;
|
||||
int col_count = 0;
|
||||
struct diskio_stat *cur;
|
||||
unsigned int reads, writes;
|
||||
unsigned int total_reads = 0, total_writes = 0;
|
||||
|
||||
stats.current = 0;
|
||||
stats.current_read = 0;
|
||||
stats.current_write = 0;
|
||||
|
||||
if (!(fp = open_file("/proc/diskstats", &rep))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* read reads and writes from all disks (minor = 0), including cd-roms
|
||||
* and floppies, and sum them up */
|
||||
while (fgets(buf, 512, fp)) {
|
||||
col_count = sscanf(buf, "%u %u %s %*u %*u %u %*u %*u %*u %u", &major,
|
||||
&minor, devbuf, &reads, &writes);
|
||||
/* ignore subdevices (they have only 3 matching entries in their line)
|
||||
* and virtual devices (LVM, network block devices, RAM disks, Loopback)
|
||||
*
|
||||
* XXX: ignore devices which are part of a SW RAID (MD_MAJOR) */
|
||||
if (col_count == 5 && major != LVM_BLK_MAJOR && major != NBD_MAJOR
|
||||
&& major != RAMDISK_MAJOR && major != LOOP_MAJOR) {
|
||||
total_reads += reads;
|
||||
total_writes += writes;
|
||||
} else {
|
||||
col_count = sscanf(buf, "%u %u %s %*u %u %*u %u",
|
||||
&major, &minor, devbuf, &reads, &writes);
|
||||
if (col_count != 5) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cur = stats.next;
|
||||
while (cur && strcmp(devbuf, cur->dev))
|
||||
cur = cur->next;
|
||||
|
||||
if (cur)
|
||||
update_diskio_values(cur, reads, writes);
|
||||
}
|
||||
update_diskio_values(&stats, total_reads, total_writes);
|
||||
fclose(fp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user