Version 2.3.8 - Handle dynamic virtual disk major numbers.

Handle dynamic disk major numbers for dm and mdp virtual devices and don't
add their data to the composite disk.

Disk panel labels configurable - probably mostly useful for user labeling
of virtual disks.

Use wrap bytes instead of discarding data when cumulative chart data overflows.

Pavel Reznicek patch: Theme changes key changed to shift pageup/pagedown.

Ville Skytta patch: indentation cleanup and os_release() bugfix.
This commit is contained in:
Bill Wilson 2016-09-07 10:02:32 -05:00
parent b9e3e896ef
commit 493b23da0e
12 changed files with 513 additions and 356 deletions

View File

@ -90,7 +90,7 @@ BINMODE = 755
#GTOP_LIBS_D = -L$(GTOP_PREFIX)/lib -lgtop -lgtop_common -lgtop_sysdeps
#export GTOP_INCLUDE GTOP_LIBS GTOP_LIBS_D
VERSION = 2.3.8-pre1
VERSION = 2.3.8
INSTALLROOT ?= $(DESTDIR)$(PREFIX)

File diff suppressed because it is too large Load Diff

View File

@ -109,7 +109,8 @@
#define GKRELLMD_VERSION_MAJOR 2
#define GKRELLMD_VERSION_MINOR 3
#define GKRELLMD_VERSION_REV 8
#define GKRELLMD_EXTRAVERSION "-pre1"
#define GKRELLMD_EXTRAVERSION ""
//#define GKRELLMD_EXTRAVERSION "-pre1"
#define GKRELLMD_CHECK_VERSION(major,minor,rev) \
(GKRELLMD_VERSION_MAJOR > (major) || \

View File

@ -11,7 +11,7 @@
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1 VERSIONINFO
FILEVERSION 2,3,7,0
FILEVERSION 2,3,8,0
PRODUCTVERSION 0,0,0,0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
@ -22,12 +22,12 @@ BEGIN
BEGIN
VALUE "CompanyName", ""
VALUE "FileDescription", "GKrellM Daemon"
VALUE "FileVersion", "2.3.7"
VALUE "FileVersion", "2.3.8"
VALUE "InternalName", "gkrellmd"
VALUE "LegalCopyright", "Copyright (C) 1999-2016 Bill Wilson"
VALUE "OriginalFilename", "gkrellmd.exe"
VALUE "ProductName", "GKrellM"
VALUE "ProductVersion", "2.3.7"
VALUE "ProductVersion", "2.3.8"
END
END
BLOCK "VarFileInfo"

View File

@ -171,11 +171,11 @@ read_battery_demo(void)
static gboolean
setup_battery_interface(void)
{
if (!read_battery_data && !_GK.client_mode && gkrellm_sys_battery_init())
read_battery_data = gkrellm_sys_battery_read_data;
if (!read_battery_data && !_GK.client_mode && gkrellm_sys_battery_init())
read_battery_data = gkrellm_sys_battery_read_data;
if (_GK.demo)
read_battery_data = read_battery_demo;
return read_battery_data ? TRUE : FALSE;
return read_battery_data ? TRUE : FALSE;
}
void

View File

@ -698,7 +698,7 @@ gkrellm_alloc_chartdata(GkrellmChart *cp)
cd->w = w;
if (cd->data)
g_free(cd->data);
cd->data = (gint *) g_new0(gint, w);
cd->data = (gulong *) g_new0(gulong, w);
cd->maxval = 0;
cp->position = cp->w - 1;
cp->tail = cp->position;
@ -847,8 +847,14 @@ gkrellm_store_chartdatav(GkrellmChart *cp, gulong total, va_list args)
}
/* Prime the pump. Also handle data wrap around or reset to zero.
*/
if (cd->current < cd->previous || !cp->primed)
cd->wrap = 0;
if (!cp->primed)
cd->previous = cd->current;
else if (cd->current < cd->previous)
{
cd->wrap = (gulong) -1 - cd->previous;
cd->previous = 0;
}
}
if (total < cp->previous_total || !cp->primed)
cp->previous_total = total; /* Wrap around, this store won't scale */
@ -871,7 +877,7 @@ gkrellm_store_chartdatav(GkrellmChart *cp, gulong total, va_list args)
{
cd = (GkrellmChartdata *) list->data;
cd->discard = cd->data[cp->tail];
cd->data[n] = (gint)(cd->current - cd->previous);
cd->data[n] = (gulong)(cd->current - cd->previous) + cd->wrap;
cd->previous = cd->current;
/* If using totals, scale the stored data to range between 0 and the

View File

@ -49,7 +49,8 @@
typedef struct
{
gchar *name,
*label; /* Possibly translated name */
*default_label, /* Possibly translated name */
*label;
GtkWidget *vbox;
GtkWidget *enable_button;
GkrellmChart *chart;
@ -139,7 +140,7 @@ lookup_disk_by_name(const gchar *name)
| written into the config. XXX remove this eventually.
*/
if ( (disk == composite_disk || assign_method == DISK_ASSIGN_NTH)
&& !strcmp(name, disk->label))
&& !strcmp(name, disk->default_label))
return disk;
}
return NULL;
@ -152,6 +153,7 @@ disk_new(const gchar *name, const gchar *label)
disk = g_new0(DiskMon, 1);
disk->name = g_strdup(name);
disk->default_label = g_strdup(label);
disk->label = g_strdup(label);
disk->launch.command = g_strdup("");
disk->launch.tooltip_comment = g_strdup("");
@ -944,11 +946,11 @@ save_disk_config(FILE *f)
have_enabled_subdisks = (disk->subdisk == -1) ?
any_enabled_subdisks(list->next) : FALSE;
fprintf(f, "%s device %s %d %d %d %d %d %d %d\n",
fprintf(f, "%s device %s %d %d %d %d %d %d %d %s\n",
DISK_CONFIG_KEYWORD,
disk->name, disk->major, disk->minor, disk->order,
disk->enabled, disk->extra_info, disk->subdisk,
have_enabled_subdisks);
have_enabled_subdisks, disk->label);
if (*(disk->launch.command) != '\0')
fprintf(f, "%s launch %s %s\n", DISK_CONFIG_KEYWORD,
disk->name, disk->launch.command);
@ -974,7 +976,7 @@ load_disk_config(gchar *arg)
{
DiskMon *disk = NULL;
gchar config[32], item[CFG_BUFSIZE],
name[CFG_BUFSIZE], item1[CFG_BUFSIZE];
name[CFG_BUFSIZE], item1[CFG_BUFSIZE], disk_label[64];
gint major, minor, enabled, extra, order, subdisk = -1;
gint n;
gboolean enabled_subdisks = TRUE;
@ -997,10 +999,10 @@ load_disk_config(gchar *arg)
| if user changes kernel version.
*/
if ( config_assign_method == assign_method
&& sscanf(item1, "%d %d %d %d %d %d %d",
&& (n = sscanf(item1, "%d %d %d %d %d %d %d %63s",
&major, &minor, &order,
&enabled, &extra,
&subdisk, &enabled_subdisks) >= 5
&subdisk, &enabled_subdisks, disk_label)) >= 5
)
{
/* A disk in the config may not have been found in the above
@ -1023,6 +1025,8 @@ load_disk_config(gchar *arg)
{
disk->enabled = enabled;
disk->extra_info = extra;
if (n >= 8)
gkrellm_dup_string(&disk->label, disk_label);
}
}
return;
@ -1054,11 +1058,14 @@ enum
{
NAME_COLUMN,
ENABLE_COLUMN,
LABEL_COLUMN,
DISK_COLUMN,
VISIBLE_COLUMN,
IMAGE_COLUMN,
N_COLUMNS
};
static GtkTreeModel *disk_model;
static GtkTreeView *treeview;
static GtkTreeRowReference *row_reference;
@ -1082,7 +1089,9 @@ create_model(void)
tree = gtk_tree_store_new(N_COLUMNS,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
G_TYPE_STRING,
G_TYPE_POINTER,
G_TYPE_BOOLEAN,
GDK_TYPE_PIXBUF);
for (list = disk_mon_list; list; )
{
@ -1090,16 +1099,20 @@ create_model(void)
gtk_tree_store_append(tree, &iter, NULL);
if (list == disk_mon_list)
gtk_tree_store_set(tree, &iter,
NAME_COLUMN, _("Composite chart combines data for all disks"),
NAME_COLUMN, _("Composite chart"),
ENABLE_COLUMN, disk->enabled,
LABEL_COLUMN, disk->label,
DISK_COLUMN, disk,
VISIBLE_COLUMN, TRUE,
-1);
else
{
gtk_tree_store_set(tree, &iter,
NAME_COLUMN, disk->label,
NAME_COLUMN, disk->default_label,
ENABLE_COLUMN, disk->enabled,
LABEL_COLUMN, disk->label,
DISK_COLUMN, disk,
VISIBLE_COLUMN, TRUE,
-1);
if (disk->alert)
gtk_tree_store_set(tree, &iter,
@ -1112,9 +1125,11 @@ create_model(void)
break;
gtk_tree_store_append(tree, &citer, &iter);
gtk_tree_store_set(tree, &citer,
NAME_COLUMN, disk->name,
NAME_COLUMN, disk->default_label,
ENABLE_COLUMN, disk->enabled,
LABEL_COLUMN, disk->label,
DISK_COLUMN, disk,
VISIBLE_COLUMN, TRUE,
-1);
if (disk->alert)
gtk_tree_store_set(tree, &citer,
@ -1139,7 +1154,7 @@ add_launch_entry(GtkWidget *vbox, DiskMon *disk)
{
disk->launch_table = gkrellm_gtk_launcher_table_new(vbox, 1);
gkrellm_gtk_config_launcher(disk->launch_table, 0, &disk->launch_entry,
&disk->tooltip_entry, disk->label,
&disk->tooltip_entry, disk->default_label,
&disk->launch);
g_signal_connect(G_OBJECT(disk->launch_entry), "changed",
G_CALLBACK(cb_launch_entry), disk);
@ -1249,6 +1264,49 @@ cb_set_alert(GtkWidget *button, gpointer data)
gkrellm_alert_config_window(&disk->alert);
}
static void
label_edited_cb(GtkCellRendererText *cell, gchar *path_string,
gchar *new_label, gpointer data)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *path;
DiskMon *disk;
model = disk_model;
path = gtk_tree_path_new_from_string(path_string);
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_path_free(path);
gtk_tree_model_get(model, &iter,
DISK_COLUMN, &disk,
-1);
if (!*new_label)
new_label = disk->default_label;
gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
LABEL_COLUMN, new_label, -1);
if (strcmp(new_label, disk->label))
{
gkrellm_dup_string(&disk->label, new_label);
gkrellm_panel_configure(disk->chart->panel, disk->label,
gkrellm_panel_style(style_id));
gkrellm_panel_create(disk->vbox, mon_disk, disk->chart->panel);
}
#if 0
if (gkrellm_locale_dup_string(&s->name, new_label, &s->name_locale))
{
gkrellm_sensors_rebuild(s->type == SENSOR_TEMPERATURE,
s->type == SENSOR_FAN, s->type == SENSOR_VOLTAGE);
if (s->alert)
{
g_free(s->alert->name);
s->alert->name = g_strdup(s->name);
// gkrellm_reset_alert(s->alert);
}
}
#endif
}
static void
cb_tree_selection_changed(GtkTreeSelection *selection, gpointer data)
@ -1391,6 +1449,7 @@ create_disk_tab(GtkWidget *tab_vbox)
gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
model = create_model();
disk_model = model;
treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
gtk_tree_view_set_rules_hint(treeview, TRUE);
@ -1408,6 +1467,15 @@ create_disk_tab(GtkWidget *tab_vbox)
renderer,
"text", NAME_COLUMN,
NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Label"),
renderer,
"text", LABEL_COLUMN,
"editable", TRUE,
"visible", VISIBLE_COLUMN,
NULL);
g_signal_connect(G_OBJECT(renderer), "edited",
G_CALLBACK(label_edited_cb), NULL);
renderer = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_insert_column_with_attributes(treeview, -1, "",

View File

@ -109,7 +109,8 @@
#define GKRELLM_VERSION_MAJOR 2
#define GKRELLM_VERSION_MINOR 3
#define GKRELLM_VERSION_REV 8
#define GKRELLM_EXTRAVERSION "-pre1"
#define GKRELLM_EXTRAVERSION ""
//#define GKRELLM_EXTRAVERSION "-pre1"
#define GKRELLM_CHECK_VERSION(major,minor,rev) \
(GKRELLM_VERSION_MAJOR > (major) || \
@ -721,11 +722,12 @@ typedef struct
gchar *label;
gulong current,
previous,
wrap,
discard;
gboolean monotonic;
GkrellmChartlayer layer; /* The image + grid for this data layer */
GdkBitmap *data_bitmap; /* Draw data here, use as clipmask for layer*/
gint *data;
gulong *data;
gint draw_style;
gboolean inverted;
@ -742,7 +744,7 @@ typedef struct
gint y, /* Each data layer draws at an offset y and */
h, /* within height h of its parent GkrellmChart*/
w; /* Width of data allocated. */
gint maxval;
gulong maxval;
}
GkrellmChartdata;

View File

@ -2483,9 +2483,9 @@ static GtkActionEntry ui_entries[] =
{ "ThemeMenuAction", NULL, N_("Theme"),
NULL, NULL, NULL },
{ "ThemeAltNextAction", NULL, N_("Next"),
"Page_Up", NULL, G_CALLBACK(cb_load_theme) },
"<shift>Page_Up", NULL, G_CALLBACK(cb_load_theme) },
{ "ThemeAltPrevAction", NULL, N_("Prev"),
"Page_Down", NULL, G_CALLBACK(cb_load_theme) },
"<shift>Page_Down", NULL, G_CALLBACK(cb_load_theme) },
{ "ThemeNextAction", NULL, N_("Theme next"),
"<control>Page_Up", NULL, G_CALLBACK(cb_load_theme) },
{ "ThemePrevAction", NULL, N_("Theme prev"),

View File

@ -708,16 +708,16 @@ create_chart(MeminfoChart *mc, gint first_create)
mc->out_cd = gkrellm_add_default_chartdata(cp, _("Swap Out"));
mc->in_cd = gkrellm_add_default_chartdata(cp, _("Swap In"));
gkrellm_set_draw_chart_function(cp, refresh_chart, mc);
gkrellm_chartconfig_fixed_grids_connect(cp->config,
setup_scaling, mc);
gkrellm_chartconfig_grid_resolution_connect(cp->config,
setup_scaling, mc);
gkrellm_chartconfig_grid_resolution_adjustment(cp->config, TRUE,
0, (gfloat) MIN_GRID_RES, (gfloat) MAX_GRID_RES, 0, 0, 0, 70);
gkrellm_chartconfig_grid_resolution_label(cp->config,
_("Swap in/out pages per sec"));
if (gkrellm_get_chartconfig_grid_resolution(cp->config) < MIN_GRID_RES)
gkrellm_set_chartconfig_grid_resolution(cp->config, DEFAULT_GRID_RES);
gkrellm_chartconfig_fixed_grids_connect(cp->config,
setup_scaling, mc);
gkrellm_chartconfig_grid_resolution_connect(cp->config,
setup_scaling, mc);
gkrellm_chartconfig_grid_resolution_adjustment(cp->config, TRUE,
0, (gfloat) MIN_GRID_RES, (gfloat) MAX_GRID_RES, 0, 0, 0, 70);
gkrellm_chartconfig_grid_resolution_label(cp->config,
_("Swap in/out pages per sec"));
if (gkrellm_get_chartconfig_grid_resolution(cp->config) < MIN_GRID_RES)
gkrellm_set_chartconfig_grid_resolution(cp->config, DEFAULT_GRID_RES);
gkrellm_alloc_chartdata(cp);

View File

@ -64,7 +64,7 @@ os_release(gint major, gint minor, gint rev)
{
if ( os_major > major
|| (os_major == major && os_minor > minor)
|| (os_major == os_major && os_minor == minor && os_rev >= rev)
|| (os_major == major && os_minor == minor && os_rev >= rev)
)
return TRUE;
return FALSE;
@ -304,8 +304,12 @@ gkrellm_sys_cpu_init(void)
/* ===================================================================== */
/* Disk monitor interface */
// http://stackoverflow.com/questions/1823743/knowing-a-device-special-file-major-and-minor-numbers-in-linux
// https://fedoraproject.org/wiki/BlockDeviceOddities
#define PROC_PARTITIONS_FILE "/proc/partitions"
#define PROC_DISKSTATS_FILE "/proc/diskstats"
#define PROC_DEVICES_FILE "/proc/devices"
#include <linux/major.h>
#if ! defined (SCSI_DISK0_MAJOR)
@ -314,9 +318,6 @@ gkrellm_sys_cpu_init(void)
#if ! defined (MD_MAJOR)
#define MD_MAJOR 9
#endif
#if !defined(DM_MAJOR)
#define DM_MAJOR 254
#endif
#if !defined(IDE4_MAJOR)
#define IDE4_MAJOR 56
@ -413,24 +414,79 @@ static struct _disk_name_map
{"cc6d", COMPAQ_CISS_MAJOR + 6, 16, '0' }, /* 110: c6d0-c6d15 */
{"cc7d", COMPAQ_CISS_MAJOR + 7, 16, '0' }, /* 111: c7d0-c7d15 */
{"dm-", DM_MAJOR, 256, '0' }, /* 254: dm-0 - dm-255 */
{"dm-", 0 /* dynamic major */, 256, '0' }, /* 254: dm-0 - dm-255 */
{"mdp", 0 /* dynamic major */, 256, '0' }, /* 254: dm-0 - dm-255 */
{"fd", FLOPPY_MAJOR, 0, '0' } /* 2: fd0-fd3 */
};
static gboolean
disk_major_ok(gint major)
#define DISK_MAJOR_STATUS_SIZE 512
#define MAJOR_STATUS_UNKNOWN 0
#define MAJOR_STATUS_KNOWN 1
#define MAJOR_STATUS_VIRTUAL 2
#define MAJOR_STATUS_REJECT 4
static guchar disk_major_status[DISK_MAJOR_STATUS_SIZE];
/* Init table with known disk major numbers.
*/
static void
disk_major_status_init(void)
{
gint i;
int i, m;
for (i = 0; i < sizeof(disk_name_map) / sizeof(struct _disk_name_map); ++i)
{
if (major == disk_name_map[i].major)
return TRUE;
if (i >= DISK_MAJOR_STATUS_SIZE)
continue;
m = disk_name_map[i].major;
disk_major_status[m] = MAJOR_STATUS_KNOWN;
}
return FALSE;
}
/* For unknown disk major numbers, check /proc/devices to see if this
| major number is an expected dynamic virtual disk. Otherwise
| the disk will be rejected.
*/
static gboolean
dynamic_disk_major(int major)
{
FILE *f;
gboolean result = FALSE;
int m;
gchar buf[128], name_buf[32];
if ((f = fopen(PROC_DEVICES_FILE, "r")) != NULL)
{
while ((fgets(buf, sizeof(buf), f)) != NULL)
{
if (sscanf(buf, "%d %31s", &m, name_buf) != 2)
continue;
if ( ( !strcmp(name_buf, "device-mapper")
|| !strcmp(name_buf, "mdp")
)
&& m == major
&& m < DISK_MAJOR_STATUS_SIZE
)
{
disk_major_status[m] = (MAJOR_STATUS_KNOWN | MAJOR_STATUS_VIRTUAL);
result = TRUE;
gkrellm_debug(DEBUG_SYSDEP,
"Adding dynamic disk major: %d %s\n", major, name_buf);
break;
}
}
fclose(f);
}
if (result == FALSE)
{
gkrellm_debug(DEBUG_SYSDEP, "Unknown disk major number: %d\n", major);
disk_major_status[major] = MAJOR_STATUS_REJECT;
}
return result;
}
gchar *
gkrellm_sys_disk_name_from_device(gint device_number, gint unit_number,
gint *order)
@ -509,8 +565,8 @@ disk_get_device_name(gint major, gint minor, gchar *disk, gchar *partition)
{ /* Have a simple name like hda, hda1, sda, ... */
d = disk;
p = partition;
while (*d && *p && *d++ == *p++)
;
while (*d && *p && *d == *p)
++d, ++p;
/* Check that p points to valid partition number. Should be a digit
| unless disk is mmcblkN where the partition number has a leading 'p'
@ -564,8 +620,7 @@ linux_read_proc_diskstats(void)
gchar buf[1024], part[128], disk[128];
gint major, minor, n;
gulong rd, wr, rd1, wr1;
gboolean inactivity_override, is_MD;
static gboolean initial_read = TRUE;
gboolean is_virtual;
if (!f && (f = fopen(PROC_DISKSTATS_FILE, "r")) == NULL)
return;
@ -588,34 +643,40 @@ linux_read_proc_diskstats(void)
wr = wr1;
}
/* Make sure all real disks get reported (so they will be added to the
| disk monitor in order) the first time this function is called.
| Use disk_major_ok() instead of simply initial_read until I'm sure
| I'm testing for all the right "major" exclusions.
| Note: disk_get_device_name() assumes "part[]" retains results from
if ( major >= DISK_MAJOR_STATUS_SIZE
|| disk_major_status[major] == MAJOR_STATUS_REJECT
)
continue;
/* Check for a dynamic major disk number, assumed to be virtual
*/
if ( disk_major_status[major] == MAJOR_STATUS_UNKNOWN
&& !dynamic_disk_major(major)
)
continue;
/* Note: disk_get_device_name() assumes "part[]" retains results from
| previous calls and that disk/subdisk parsing will be in order
| (ie hda will be encountered before hda1).
*/
inactivity_override = initial_read ? disk_major_ok(major) : FALSE;
if ( (n != 7 && n != 6)
|| (rd == 0 && wr == 0 && !inactivity_override)
|| (rd == 0 && wr == 0)
|| major == LVM_BLK_MAJOR || major == NBD_MAJOR
|| major == RAMDISK_MAJOR || major == LOOP_MAJOR
|| major == DM_MAJOR
|| !disk_get_device_name(major, minor, disk, part)
)
continue;
is_MD = (major == MD_MAJOR);
is_virtual = ( major == MD_MAJOR
|| (disk_major_status[major] & MAJOR_STATUS_VIRTUAL)
);
if (part[0] == '\0')
gkrellm_disk_assign_data_by_name(disk, 512 * rd, 512 * wr, is_MD);
gkrellm_disk_assign_data_by_name(disk, 512 * rd, 512 * wr, is_virtual);
else
gkrellm_disk_subdisk_assign_data_by_name(part, disk,
512 * rd, 512 * wr);
}
rewind(f);
initial_read = FALSE;
}
/* /proc/partitions can have diskstats in 2.4 kernels or in 2.5+ it's just
@ -730,6 +791,8 @@ gkrellm_sys_disk_init(void)
}
if (f)
fclose(f);
disk_major_status_init();
gkrellm_debug(DEBUG_SYSDEP,
"diskstats=%d partition_stats=%d sysfs_stats=%d\n", have_diskstats,
have_partition_stats, have_sysfs_stats);

View File

@ -18,7 +18,7 @@ IDI_ICON3 ICON "gkrellm.ico"
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1 VERSIONINFO
FILEVERSION 2,3,7,0
FILEVERSION 2,3,8,0
PRODUCTVERSION 0,0,0,0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
@ -29,12 +29,12 @@ BEGIN
BEGIN
VALUE "CompanyName", ""
VALUE "FileDescription", "GKrellM"
VALUE "FileVersion", "2.3.7"
VALUE "FileVersion", "2.3.8"
VALUE "InternalName", "gkrellm"
VALUE "LegalCopyright", "Copyright (C) 1999-2016 Bill Wilson"
VALUE "OriginalFilename", "gkrellm.exe"
VALUE "ProductName", "GKrellM"
VALUE "ProductVersion", "2.3.7"
VALUE "ProductVersion", "2.3.8"
END
END
BLOCK "VarFileInfo"