📄 disk.c
字号:
/* GKrellM| Copyright (C) 1999-2006 Bill Wilson|| Author: Bill Wilson billw@gkrellm.net| Latest versions might be found at: http://gkrellm.net|| This program is free software which I release under the GNU General Public| License. You may redistribute and/or modify this program under the terms| of that license as published by the Free Software Foundation; either| version 2 of the License, or (at your option) any later version.|| This program is distributed in the hope that it will be useful,| but WITHOUT ANY WARRANTY; without even the implied warranty of| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the| GNU General Public License for more details. Version 2 is in the| COPYRIGHT file in the top level directory of this distribution.| | To get a copy of the GNU General Puplic License, write to the Free Software| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "gkrellm.h"#include "gkrellm-private.h"#include "gkrellm-sysdeps.h"#define DISK_ASSIGN_BY_DEVICE 0#define DISK_ASSIGN_NTH 1#define DISK_ASSIGN_BY_NAME 2#define DISK_CONFIG_KEYWORD "disk"#define MIN_GRID_RES 10#define MAX_GRID_RES 100000000#define DEFAULT_GRID_RES 2000typedef struct { gchar *name, *label; /* Possibly translated name */ GtkWidget *vbox; GtkWidget *enable_button; GkrellmChart *chart; GkrellmChartdata *read_cd, *write_cd; GkrellmChartconfig *chart_config; GkrellmAlert *alert; GtkWidget *alert_config_read_button, *alert_config_write_button; gboolean alert_uses_read, alert_uses_write, new_text_format; GkrellmDecal *temp_decal; gint save_label_position; gint enabled; gint major, minor, subdisk, order; gint new_disk; gint extra_info; GkrellmLauncher launch; GtkWidget *launch_entry, *tooltip_entry; GtkWidget *launch_table; guint64 rb, wb; } DiskMon;static void cb_alert_config(GkrellmAlert *ap, DiskMon *disk);static void cb_alert_config_create(GkrellmAlert *ap, GtkWidget *vbox, DiskMon *disk);static GkrellmMonitor *mon_disk;static gint n_disks;static GList *disk_mon_list;static DiskMon *composite_disk;static gint ascent;static gint style_id;static gint assign_method;static gboolean sys_handles_composite_reset;static gboolean units_are_blocks;static void (*read_disk_data)();static gchar *(*name_from_device)();static gint (*order_from_name)();DiskMon *lookup_disk_by_device(gint major, gint minor) { DiskMon *disk; GList *list; for (list = disk_mon_list->next; list; list = list->next) { disk = (DiskMon * ) list->data; if (disk->major == major && disk->minor == minor) return disk; } return NULL; }static DiskMon *lookup_disk_by_name(gchar *name) { DiskMon *disk; GList *list; for (list = disk_mon_list; list; list = list->next) { disk = (DiskMon * ) list->data; if (!strcmp(name, disk->name)) return disk; /* Pre 2.1.15 config compatibility where translated "Disk" was | written into the config. XXX remove this eventually. */ if ( (disk == composite_disk || assign_method == DISK_ASSIGN_NTH) && !strcmp(name, disk->label)) return disk; } return NULL; }static DiskMon *disk_new(gchar *name, gchar *label) { DiskMon *disk; disk = g_new0(DiskMon, 1); disk->name = g_strdup(name); disk->label = g_strdup(label); disk->launch.command = g_strdup(""); disk->launch.tooltip_comment = g_strdup(""); disk->alert_uses_read = disk->alert_uses_write = TRUE; disk->extra_info = TRUE; return disk; }static DiskMon *add_disk(gchar *name, gchar *label, gint major, gint minor, gint order) { DiskMon *disk; GList *list; gint i; if (lookup_disk_by_name(name)) return NULL; disk = disk_new(name, label); disk->major = major; disk->minor = minor; disk->order = order; disk->subdisk = -1; if (order >= 0) { ++disk->order; /* Skip the composite disk */ for (i = 1, list = disk_mon_list->next; list; list = list->next, ++i) if (disk->order < ((DiskMon *) list->data)->order) break; disk_mon_list = g_list_insert(disk_mon_list, disk, i); } else disk_mon_list = g_list_append(disk_mon_list, disk); ++n_disks; return disk; }static DiskMon *add_subdisk(gchar *subdisk_name, gchar *disk_name, gint subdisk) { DiskMon *disk, *sdisk; GList *list = NULL; for (list = disk_mon_list->next; list; list = list->next) { disk = (DiskMon * ) list->data; if (!strcmp(disk_name, disk->name)) break; } if (!list) return NULL; sdisk = disk_new(subdisk_name, subdisk_name); sdisk->order = disk->order; sdisk->subdisk = subdisk; for (list = list->next; list; list = list->next) { disk = (DiskMon * ) list->data; if (disk->subdisk == -1 || disk->subdisk > subdisk) break; } disk_mon_list = g_list_insert_before(disk_mon_list, list, sdisk); ++n_disks; return sdisk; }static voiddisk_assign_data(DiskMon *disk, guint64 rb, guint64 wb, gboolean virtual) { if (!disk) return; disk->rb = rb; disk->wb = wb; /* Add data to composite disk if this is not a subdisk (partition) and | not a virtual disk (eg /dev/mdX software RAID multi-disk). */ if (disk->subdisk == -1 && !virtual) { composite_disk->rb += rb; composite_disk->wb += wb; } }static gbooleansetup_disk_interface(void) { if (!read_disk_data && !_GK.client_mode && gkrellm_sys_disk_init()) { read_disk_data = gkrellm_sys_disk_read_data; name_from_device = gkrellm_sys_disk_name_from_device; order_from_name = gkrellm_sys_disk_order_from_name; } /* Get a read in so I'll know the assign_method before config is loaded. */ if (read_disk_data) (*read_disk_data)(); return read_disk_data ? TRUE : FALSE; }/* ------------- Disk monitor to system dependent interface ------------- */voidgkrellm_disk_client_divert(void (*read_func)(), gchar *(*name_from_device_func)(), gint (*order_from_name_func)()) { read_disk_data = read_func; name_from_device = name_from_device_func; order_from_name = order_from_name_func; }voidgkrellm_disk_reset_composite(void) { composite_disk->rb = 0; composite_disk->wb = 0; sys_handles_composite_reset = TRUE; }voidgkrellm_disk_units_are_blocks(void) { units_are_blocks = TRUE; } voidgkrellm_disk_assign_data_by_device(gint device_number, gint unit_number, guint64 rb, guint64 wb, gboolean virtual) { DiskMon *disk; gchar *name; gint order = -1; assign_method = DISK_ASSIGN_BY_DEVICE; disk = lookup_disk_by_device(device_number, unit_number); if (!disk && name_from_device) { name = (*name_from_device)(device_number, unit_number, &order); if (name) disk = add_disk(name, name, device_number, unit_number, order); } disk_assign_data(disk, rb, wb, virtual); }voidgkrellm_disk_assign_data_nth(gint n, guint64 rb, guint64 wb, gboolean virtual) { DiskMon *disk; gchar name[32], label[32]; assign_method = DISK_ASSIGN_NTH; if (n < n_disks) disk = (DiskMon *) g_list_nth_data(disk_mon_list, n + 1); else { sprintf(name, "%s%c", "Disk", 'A' + n); sprintf(label, "%s%c", _("Disk"), 'A' + n); disk = add_disk(name, label, 0, 0, n); } disk_assign_data(disk, rb, wb, virtual); }voidgkrellm_disk_assign_data_by_name(gchar *name, guint64 rb, guint64 wb, gboolean virtual) { DiskMon *disk; gint order = -1; assign_method = DISK_ASSIGN_BY_NAME; if (!name) return; disk = lookup_disk_by_name(name); if (!disk) { if (order_from_name) order = (*order_from_name)(name); disk = add_disk(name, name, 0, 0, order); } disk_assign_data(disk, rb, wb, virtual); }voidgkrellm_disk_subdisk_assign_data_by_name(gchar *subdisk_name, gchar *disk_name, guint64 rb, guint64 wb) { DiskMon *disk; gchar *s, *endptr; gint subdisk; assign_method = DISK_ASSIGN_BY_NAME; if (!subdisk_name || !disk_name) return; disk = lookup_disk_by_name(subdisk_name); if (!disk) { /* A subdisk name is expected to be the disk_name with a number string | appended. Eg. "hda1" is a subdisk_name of disk_name "hda" */ s = subdisk_name + strlen(disk_name); subdisk = strtol(s, &endptr, 0); if (!*s || *endptr) return; disk = add_subdisk(subdisk_name, disk_name, subdisk); } disk_assign_data(disk, rb, wb, FALSE); }/* ----------- End of Disk monitor to system dependent interface ---------- */static GkrellmSizeAbbrev disk_blocks_abbrev[] = { { KB_SIZE(1), 1, "%.0f" }, { KB_SIZE(20), KB_SIZE(1), "%.1fK" }, { MB_SIZE(1), KB_SIZE(1), "%.0fK" }, { MB_SIZE(20), MB_SIZE(1), "%.1fM" }, { MB_SIZE(50), MB_SIZE(1), "%.0fM" } };static gchar *text_format, *text_format_locale;static voidformat_disk_data(DiskMon *disk, gchar *src_string, gchar *buf, gint size) { GkrellmChart *cp; gchar c, *s; size_t tbl_size; gint len, r_blocks, w_blocks, blocks; if (!buf || size < 1) return; --size; *buf = '\0'; if (!src_string) return; cp = disk->chart; r_blocks = gkrellm_get_current_chartdata(disk->read_cd); w_blocks = gkrellm_get_current_chartdata(disk->write_cd); tbl_size = sizeof(disk_blocks_abbrev) / sizeof(GkrellmSizeAbbrev); for (s = src_string; *s != '\0' && size > 0; ++s) { len = 1; if (*s == '$' && *(s + 1) != '\0') { blocks = -1; if ((c = *(s + 1)) == 'T') blocks = r_blocks + w_blocks; else if (c == 'M') blocks = gkrellm_get_chart_scalemax(cp); else if (c == 'r') blocks = r_blocks; else if (c == 'w') blocks = w_blocks; else if (c == 'H') len = snprintf(buf, size, "%s", gkrellm_sys_get_host_name()); else { *buf = *s; if (size > 1) { *(buf + 1) = *(s + 1); ++len; } } if (blocks >= 0) len = gkrellm_format_size_abbrev(buf, size, (gfloat) blocks, &disk_blocks_abbrev[0], tbl_size); ++s; } else *buf = *s; size -= len; buf += len; } *buf = '\0'; }static voiddraw_disk_extra(DiskMon *disk) { gchar buf[128]; if (!disk->chart || !disk->extra_info) return; format_disk_data(disk, text_format_locale, buf, sizeof(buf)); if (!disk->new_text_format) gkrellm_chart_reuse_text_format(disk->chart); disk->new_text_format = FALSE; gkrellm_draw_chart_text(disk->chart, style_id, buf); }static voidcb_command_process(GkrellmAlert *alert, gchar *src, gchar *dst, gint len, DiskMon *disk) { if (disk->chart) format_disk_data(disk, src, dst, len); }static voiddraw_disk_chart(DiskMon *disk) { gkrellm_draw_chartdata(disk->chart); draw_disk_extra(disk); gkrellm_draw_chart_to_screen(disk->chart); }static voidcb_disk_temp_alert_trigger(GkrellmAlert *alert, DiskMon *disk) { GkrellmAlertdecal *ad; GkrellmDecal *d; if (alert && disk && disk->chart) { ad = &alert->ad; d = disk->temp_decal; if (d) { ad->x = d->x - 1; ad->y = d->y - 1; ad->w = d->w + 2; ad->h = d->h + 2; gkrellm_render_default_alert_decal(alert); } alert->panel = disk->chart->panel; } }gbooleangkrellm_disk_temperature_display(gpointer sr, gchar *id_name, gfloat t, gchar units) { GList *list; DiskMon *disk; GkrellmPanel *p; GkrellmDecal *decal; gchar *disk_name; gint len; gboolean display_done = FALSE, display_possible = FALSE; if ((disk_name = strrchr(id_name, '/')) != NULL) ++disk_name; else disk_name = id_name; len = strlen(disk_name); for (list = disk_mon_list; list; list = list->next) { disk = (DiskMon *) list->data; if ( strncmp(disk->name, disk_name, len) || (disk->name[len] != '\0' && !isdigit(disk->name[len])) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -