diff options
author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2024-04-22 00:35:53 -0300 |
---|---|---|
committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2024-04-22 00:35:53 -0300 |
commit | 5f01c706267c595de92406a32e7f31ef5056c2d0 (patch) | |
tree | d1e74ef54efc41ada622900fe3e2a50dee44a237 /modules/devices/storage.c | |
parent | 09fcc751ef158898c315ebc9299a0fa3a722d914 (diff) |
New upstream version 2.0.3preupstream/2.0.3pre
Diffstat (limited to 'modules/devices/storage.c')
-rw-r--r-- | modules/devices/storage.c | 509 |
1 files changed, 479 insertions, 30 deletions
diff --git a/modules/devices/storage.c b/modules/devices/storage.c index 0c393682..bbf9b195 100644 --- a/modules/devices/storage.c +++ b/modules/devices/storage.c @@ -1,10 +1,11 @@ /* * HardInfo - Displays System Information - * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org> + * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br> + * modified by Ondrej Čerman (2019-2021) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2. + * the Free Software Foundation, version 2 or later. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,12 +21,464 @@ #include "hardinfo.h" #include "devices.h" +#include "udisks2_util.h" +#include "storage_util.h" + +#define UNKIFNULL_AC(f) (f != NULL) ? f : _("(Unknown)"); gchar *storage_icons = NULL; +gchar *nvme_pci_sections(pcid *p) { + const gchar *vendor, *svendor, *product, *sproduct; + + if (!p) return NULL; + + vendor = UNKIFNULL_AC(p->vendor_id_str); + svendor = UNKIFNULL_AC(p->sub_vendor_id_str); + product = UNKIFNULL_AC(p->device_id_str); + sproduct = UNKIFNULL_AC(p->sub_device_id_str); + + gchar *vendor_device_str; + if (p->vendor_id == p->sub_vendor_id && p->device_id == p->sub_device_id) { + vendor_device_str = g_strdup_printf("[%s]\n" + /* Vendor */ "$^$%s=[%04x] %s\n" + /* Device */ "%s=[%04x] %s\n", + _("NVMe Controller"), + _("Vendor"), p->vendor_id, vendor, + _("Device"), p->device_id, product); + } else { + vendor_device_str = g_strdup_printf("[%s]\n" + /* Vendor */ "$^$%s=[%04x] %s\n" + /* Device */ "%s=[%04x] %s\n" + /* Sub-device vendor */ "$^$%s=[%04x] %s\n" + /* Sub-device */ "%s=[%04x] %s\n", + _("NVMe Controller"), + _("Vendor"), p->vendor_id, vendor, + _("Device"), p->device_id, product, + _("SVendor"), p->sub_vendor_id, svendor, + _("SDevice"), p->sub_device_id, sproduct); + } + + gchar *pcie_str; + if (p->pcie_width_curr) { + pcie_str = g_strdup_printf("[%s]\n" + /* Addy */ "%s=PCI/%s\n" + /* Width (max) */ "%s=x%u\n" + /* Speed (max) */ "%s=%0.1f %s\n", + _("PCI Express"), + _("Location"), p->slot_str, + _("Maximum Link Width"), p->pcie_width_max, + _("Maximum Link Speed"), p->pcie_speed_max, _("GT/s") ); + } else + pcie_str = strdup(""); + + gchar *ret = g_strdup_printf("%s%s", vendor_device_str, pcie_str); + g_free(vendor_device_str); + g_free(pcie_str); + return ret; +} + +gboolean __scan_udisks2_devices(void) { + GSList *node, *drives; + u2driveext *ext; + udiskd *disk; + udiskp *part; + udisksa *attrib; + gchar *udisks2_storage_list = NULL, *features = NULL, *moreinfo = NULL; + gchar *devid, *size, *tmp = NULL, *media_comp = NULL, *ven_tag = NULL; + const gchar *url, *media_label, *alabel, *icon, *media_curr = NULL; + int n = 0, i, j, m; + + // http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Drive.html#gdbus-property-org-freedesktop-UDisks2-Drive.MediaCompatibility + static struct { + char *media; + char *label; + char *icon; + } media_info[] = { + { "thumb", "Thumb-drive", "usbfldisk" }, + { "flash", "Flash Card", "usbfldisk" }, + { "flash_cf", "CompactFlash", "usbfldisk" }, + { "flash_ms", "MemoryStick", "usbfldisk" }, + { "flash_sm", "SmartMedia", "usbfldisk" }, + { "flash_sd", "SD", "usbfldisk" }, + { "flash_sdhc", "SDHC", "usbfldisk" }, + { "flash_sdxc", "SDXC", "usbfldisk" }, + { "flash_mmc", "MMC", "usbfldisk" }, + { "floppy", "Floppy Disk", "media-floppy" }, + { "floppy_zip", "Zip Disk", "media-floppy" }, + { "floppy_jaz", "Jaz Disk", "media-floppy" }, + { "optical", "Optical Disc", "cdrom" }, + { "optical_cd", "CD-ROM", "cdrom" }, + { "optical_cd_r", "CD-R", "cdrom" }, + { "optical_cd_rw", "CD-RW", "cdrom" }, + { "optical_dvd", "DVD-ROM", "cdrom" }, + { "optical_dvd_r", "DVD-R", "cdrom" }, + { "optical_dvd_rw", "DVD-RW", "cdrom" }, + { "optical_dvd_ram", "DVD-RAM", "cdrom" }, + { "optical_dvd_plus_r", "DVD+R" , "cdrom" }, + { "optical_dvd_plus_rw", "DVD+RW" , "cdrom" }, + { "optical_dvd_plus_r_dl", "DVD+R DL", "cdrom" }, + { "optical_dvd_plus_rw_dl", "DVD+RW DL", "cdrom" }, + { "optical_bd", "BD-ROM", "cdrom" }, + { "optical_bd_r", "BD-R", "cdrom" }, + { "optical_bd_re", "BD-RE", "cdrom" }, + { "optical_hddvd", "HD DVD-ROM", "cdrom" }, + { "optical_hddvd_r", "HD DVD-R", "cdrom" }, + { "optical_hddvd_rw", "HD DVD-RW", "cdrom" }, + { "optical_mo", "MO Disc", "cdrom" }, + { "optical_mrw", "MRW Media", "cdrom" }, + { "optical_mrw_w", "MRW Media (write)", "cdrom" }, + { NULL, NULL } + }; + + struct { + char *identifier; + char *label; + } smart_attrib_info[] = { + { "raw-read-error-rate", _("Read Error Rate" ) }, + { "throughput-performance", _("Throughput Performance") }, + { "spin-up-time", _("Spin-Up Time") }, + { "start-stop-count", _("Start/Stop Count") }, + { "reallocated-sector-count", _("Reallocated Sector Count") }, + { "read-channel-margin", _("Read Channel Margin") }, + { "seek-error-rate", _("Seek Error Rate") }, + { "seek-time-performance", _("Seek Timer Performance") }, + { "power-on-hours", _("Power-On Hours") }, + { "spin-retry-count", _("Spin Retry Count") }, + { "calibration-retry-count", _("Calibration Retry Count") }, + { "power-cycle-count", _("Power Cycle Count") }, + { "read-soft-error-rate", _("Soft Read Error Rate") }, + { "runtime-bad-block-total", _("Runtime Bad Block") }, + { "end-to-end-error", _("End-to-End error") }, + { "reported-uncorrect", _("Reported Uncorrectable Errors") }, + { "command-timeout", _("Command Timeout") }, + { "high-fly-writes", _("High Fly Writes") }, + { "airflow-temperature-celsius", _("Airflow Temperature") }, + { "g-sense-error-rate", _("G-sense Error Rate") }, + { "power-off-retract-count", _("Power-off Retract Count") }, + { "load-cycle-count", _("Load Cycle Count") }, + { "temperature-celsius-2", _("Temperature") }, + { "hardware-ecc-recovered", _("Hardware ECC Recovered") }, + { "reallocated-event-count", _("Reallocation Event Count") }, + { "current-pending-sector", _("Current Pending Sector Count") }, + { "offline-uncorrectable", _("Uncorrectable Sector Count") }, + { "udma-crc-error-count", _("UltraDMA CRC Error Count") }, + { "multi-zone-error-rate", _("Multi-Zone Error Rate") }, + { "soft-read-error-rate", _("Soft Read Error Rate") }, + { "run-out-cancel", _("Run Out Cancel") }, + { "flying-height", _("Flying Height") }, + { "spin-high-current", _("Spin High Current") }, + { "spin-buzz", _("Spin Buzz") }, + { "offline-seek-performance", _("Offline Seek Performance") }, + { "disk-shift", _("Disk Shift") }, + { "g-sense-error-rate-2", _("G-Sense Error Rate") }, + { "loaded-hours", _("Loaded Hours") }, + { "load-retry-count", _("Load/Unload Retry Count") }, + { "load-friction", _("Load Friction") }, + { "load-cycle-count-2", _("Load/Unload Cycle Count") }, + { "load-in-time", _("Load-in time") }, + { "torq-amp-count", _("Torque Amplification Count") }, + { "power-off-retract-count-2", _("Power-Off Retract Count") }, + { "head-amplitude", _("GMR Head Amplitude") }, + { "temperature-celsius", _("Temperature") }, + { "endurance-remaining", _("Endurance Remaining") }, + { "power-on-seconds-2", _("Power-On Hours") }, + { "good-block-rate", _("Good Block Rate") }, + { "head-flying-hours", _("Head Flying Hours") }, + { "read-error-retry-rate", _("Read Error Retry Rate") }, + { "total-lbas-written", _("Total LBAs Written") }, + { "total-lbas-read", _("Total LBAs Read") }, + { "wear-leveling-count", _("Wear leveling Count") }, + { "used-reserved-blocks-total", _("Total Used Reserved Block Count") }, + { "program-fail-count-total", _("Total Program Fail Count") }, + { "erase-fail-count-total", _("Total Erase Fail Count") }, + { "available-reserved-space", _("Available Reserved Space") }, + { "program-fail-count", _("Program Fail Count") }, + { "erase-fail-count", _("Erase Fail Count") }, + { "ta-increase-count", _("TA Counter Increased") }, + { "unused-reserved-blocks", _("Total Unused Reserved Block Count") }, + { NULL, NULL } + }; + + moreinfo_del_with_prefix("DEV:UDISKS"); + udisks2_storage_list = g_strdup(_("\n[UDisks2]\n")); + + drives = get_udisks2_drives_ext(); + for (node = drives; node != NULL; node = node->next) { + ext = (u2driveext *)node->data; + disk = ext->d; + devid = g_strdup_printf("UDISKS%d", n++); + + icon = NULL; + + media_curr = disk->media; + if (disk->media){ + for (j = 0; media_info[j].media != NULL; j++) { + if (g_strcmp0(disk->media, media_info[j].media) == 0) { + media_curr = media_info[j].label; + break; + } + } + } + + if (disk->media_compatibility){ + for (i = 0; disk->media_compatibility[i] != NULL; i++){ + media_label = disk->media_compatibility[i]; + + for (j = 0; media_info[j].media != NULL; j++) { + if (g_strcmp0(disk->media_compatibility[i], media_info[j].media) == 0) { + media_label = media_info[j].label; + if (icon == NULL) + icon = media_info[j].icon; + break; + } + } + + if (media_comp == NULL){ + media_comp = g_strdup(media_label); + } + else{ + media_comp = h_strdup_cprintf(", %s", media_comp, media_label); + } + } + } + if (icon == NULL && disk->ejectable && g_strcmp0(disk->connection_bus, "usb") == 0) { + icon = "usbfldisk"; + } + if (icon == NULL){ + icon = "hdd"; + } + + size = size_human_readable((gfloat) disk->size); + ven_tag = vendor_list_ribbon(ext->vendors, params.fmt_opts); + + udisks2_storage_list = h_strdup_cprintf("$%s$%s=%s|%s %s\n", udisks2_storage_list, devid, disk->block_dev, size, ven_tag ? ven_tag : "", disk->model); + storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, disk->model, icon); + features = h_strdup_cprintf("%s", features, disk->removable ? _("Removable"): _("Fixed")); + + if (disk->ejectable) { + features = h_strdup_cprintf(", %s", features, _("Ejectable")); + } + if (disk->smart_supported) { + features = h_strdup_cprintf(", %s", features, _("Self-monitoring (S.M.A.R.T.)")); + } + if (disk->pm_supported) { + features = h_strdup_cprintf(", %s", features, _("Power Management")); + } + if (disk->apm_supported) { + features = h_strdup_cprintf(", %s", features, _("Advanced Power Management")); + } + if (disk->aam_supported) { + features = h_strdup_cprintf(", %s", features, _("Automatic Acoustic Management")); + } + + moreinfo = g_strdup_printf(_("[Drive Information]\n" + "Model=%s\n"), + disk->model); + + if (disk->vendor && *disk->vendor) { + moreinfo = h_strdup_cprintf("$^$%s=%s\n", + moreinfo, + _("Vendor"), disk->vendor); + } + + moreinfo = h_strdup_cprintf(_("Revision=%s\n" + "Block Device=%s\n" + "Serial=%s\n" + "Size=%s\n" + "Features=%s\n"), + moreinfo, + disk->revision, + disk->block_dev, + disk->serial, + size, + features); + g_free(size); + g_free(ven_tag); + + if (disk->rotation_rate > 0) { + moreinfo = h_strdup_cprintf(_("Rotation Rate=%d RPM\n"), moreinfo, disk->rotation_rate); + } + if (media_comp || media_curr) { + moreinfo = h_strdup_cprintf(_("Media=%s\n" + "Media compatibility=%s\n"), + moreinfo, + media_curr ? media_curr : _("(None)"), + media_comp ? media_comp : _("(Unknown)")); + } + if (disk->connection_bus && strlen(disk->connection_bus) > 0) { + moreinfo = h_strdup_cprintf(_("Connection bus=%s\n"), moreinfo, disk->connection_bus); + } + + tmp = NULL; + if (disk->wwid) { + m = strlen(disk->wwid); + if (m > 2 && m % 2 == 0){ + for (j = 4; j < m; j = j + 2) { + tmp = h_strdup_cprintf("%s%c%c", tmp, j > 4 ? "-": "", disk->wwid[j], disk->wwid[j+1]); + } + } + moreinfo = h_strdup_cprintf("%s=%s\n", moreinfo, + g_str_has_prefix(disk->wwid, "nna.") ? _("WWN"): + (g_str_has_prefix(disk->wwid, "eui.") ? _("EUI "): "Unknown ID"), + tmp); + g_free(tmp); + } + else{ + moreinfo = h_strdup_cprintf("%s=%s\n", moreinfo, _("WWN / EUI"), _("(None)")); + } + + if (ext->wwid_oui.oui) { + moreinfo = h_strdup_cprintf(_("$^$%s=[%s] %s\n"), + moreinfo, + _("IEEE OUI"), ext->wwid_oui.oui, + ext->wwid_oui.vendor ? + ext->wwid_oui.vendor : _("(Unknown)")); + } + + if (ext->nvme_controller) { + gchar *nvme = nvme_pci_sections(ext->nvme_controller); + if (nvme) + moreinfo = h_strdup_cprintf("%s", moreinfo, nvme); + g_free(nvme); + } + if (disk->smart_enabled) { + moreinfo = h_strdup_cprintf(_("[Self-monitoring (S.M.A.R.T.)]\n" + "Status=%s\n" + "Bad Sectors=%" G_GINT64_FORMAT "\n" + "Power on time=%" G_GUINT64_FORMAT " days %" G_GUINT64_FORMAT " hours\n" + "Temperature=%d°C\n"), + moreinfo, + disk->smart_failing ? _("Failing"): _("OK"), + disk->smart_bad_sectors, + disk->smart_poweron/(60*60*24), (disk->smart_poweron/60/60) % 24, + disk->smart_temperature); + + if (disk->smart_attributes != NULL) { + moreinfo = h_strdup_cprintf(_("[S.M.A.R.T. Attributes]\n" + "Attribute=<tt>Value / Normalized / Worst / Threshold</tt>\n"), + moreinfo); + + attrib = disk->smart_attributes; + + while (attrib != NULL){ + tmp = g_strdup(""); + + switch (attrib->interpreted_unit){ + case UDSK_INTPVAL_SKIP: + tmp = h_strdup_cprintf("-", tmp); + break; + case UDSK_INTPVAL_MILISECONDS: + tmp = h_strdup_cprintf("%" G_GINT64_FORMAT " ms", tmp, attrib->interpreted); + break; + case UDSK_INTPVAL_HOURS: + tmp = h_strdup_cprintf("%" G_GINT64_FORMAT " h", tmp, attrib->interpreted); + break; + case UDSK_INTPVAL_CELSIUS: + tmp = h_strdup_cprintf("%" G_GINT64_FORMAT "°C", tmp, attrib->interpreted); + break; + case UDSK_INTPVAL_SECTORS: + tmp = h_strdup_cprintf(ngettext("%" G_GINT64_FORMAT " sector", + "%" G_GINT64_FORMAT " sectors", attrib->interpreted), + tmp, attrib->interpreted); + break; + case UDSK_INTPVAL_DIMENSIONLESS: + default: + tmp = h_strdup_cprintf("%" G_GINT64_FORMAT, tmp, attrib->interpreted); + break; + } + + // pad spaces to next col + j = g_utf8_strlen(tmp, -1); + if (j < 13) tmp = h_strdup_cprintf("%*c", tmp, 13 - j, ' '); + + if (attrib->value != -1) + tmp = h_strdup_cprintf("%-13d", tmp, attrib->value); + else + tmp = h_strdup_cprintf("%-13s", tmp, "???"); + + if (attrib->worst != -1) + tmp = h_strdup_cprintf("%-8d", tmp, attrib->worst); + else + tmp = h_strdup_cprintf("%-8s", tmp, "???"); + + if (attrib->threshold != -1) + tmp = h_strdup_cprintf("%d", tmp, attrib->threshold); + else + tmp = h_strdup_cprintf("???", tmp); + + + alabel = attrib->identifier; + for (i = 0; smart_attrib_info[i].identifier != NULL; i++) { + if (g_strcmp0(attrib->identifier, smart_attrib_info[i].identifier) == 0) { + alabel = smart_attrib_info[i].label; + break; + } + } + + moreinfo = h_strdup_cprintf(_("(%d) %s=<tt>%s</tt>\n"), + moreinfo, + attrib->id, alabel, tmp); + g_free(tmp); + attrib = attrib->next; + } + } + } + if (disk->partition_table || disk->partitions) { + moreinfo = h_strdup_cprintf(_("[Partition table]\n" + "Type=%s\n"), + moreinfo, + disk->partition_table ? disk->partition_table : _("(Unknown)")); + + if (disk->partitions != NULL) { + part = disk->partitions; + while (part != NULL){ + + tmp = size_human_readable((gfloat) part->size); + if (part->label) { + tmp = h_strdup_cprintf(" - %s", tmp, part->label); + } + if (part->type && part->version) { + tmp = h_strdup_cprintf(" (%s %s)", tmp, part->type, part->version); + } + else if (part->type) { + tmp = h_strdup_cprintf(" (%s)", tmp, part->type); + } + moreinfo = h_strdup_cprintf(_("Partition %s=%s\n"), + moreinfo, + part->block, tmp); + g_free(tmp); + part = part->next; + } + } + } + + moreinfo_add_with_prefix("DEV", devid, moreinfo); + g_free(devid); + g_free(features); + g_free(media_comp); + media_comp = NULL; + + features = NULL; + moreinfo = NULL; + devid = NULL; + + u2driveext_free(ext); + } + g_slist_free(drives); + + if (n) { + storage_list = h_strconcat(storage_list, udisks2_storage_list, NULL); + g_free(udisks2_storage_list); + return TRUE; + } + + g_free(udisks2_storage_list); + return FALSE; +} + /* SCSI support by Pascal F.Martin <pascalmartin@earthlink.net> */ -void -__scan_scsi_devices(void) +void __scan_scsi_devices(void) { FILE *proc_scsi; gchar buffer[256], *buf; @@ -40,12 +493,16 @@ __scan_scsi_devices(void) /* remove old devices from global device table */ moreinfo_del_with_prefix("DEV:SCSI"); - if (!g_file_test("/proc/scsi/scsi", G_FILE_TEST_EXISTS)) - return; - scsi_storage_list = g_strdup(_("\n[SCSI Disks]\n")); - if ((proc_scsi = fopen("/proc/scsi/scsi", "r"))) { + int otype = 0; + if (proc_scsi = fopen("/proc/scsi/scsi", "r")) { + otype = 1; + } else if (proc_scsi = popen("lsscsi -c", "r")) { + otype = 2; + } + + if (otype) { while (fgets(buffer, 256, proc_scsi)) { buf = g_strstrip(buffer); if (!strncmp(buf, "Host: scsi", 10)) { @@ -104,23 +561,15 @@ __scan_scsi_devices(void) } gchar *devid = g_strdup_printf("SCSI%d", n); - scsi_storage_list = h_strdup_cprintf("$%s$%s=\n", scsi_storage_list, devid, model); + scsi_storage_list = h_strdup_cprintf("$%s$scsi%d=|%s\n", scsi_storage_list, devid, scsi_controller, model); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, icon); gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"), model); - const gchar *url = vendor_get_url(model); - if (url) { - strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), - strhash, - vendor_get_name(model), - url); - } else { - strhash = h_strdup_cprintf(_("Vendor=%s\n"), - strhash, - vendor_get_name(model)); - } + strhash = h_strdup_cprintf("$^$%s=%s\n", + strhash, + _("Vendor"), model); strhash = h_strdup_cprintf(_("Type=%s\n" "Revision=%s\n" @@ -135,6 +584,7 @@ __scan_scsi_devices(void) scsi_channel, scsi_id, scsi_lun); + moreinfo_add_with_prefix("DEV", devid, strhash); g_free(devid); @@ -145,7 +595,10 @@ __scan_scsi_devices(void) scsi_controller = scsi_channel = scsi_id = scsi_lun = 0; } } - fclose(proc_scsi); + if (otype == 1) + fclose(proc_scsi); + else if (otype == 2) + pclose(proc_scsi); } if (n) { @@ -157,7 +610,8 @@ __scan_scsi_devices(void) void __scan_ide_devices(void) { FILE *proc_ide; - gchar *device, iface, *model, *media, *pgeometry = NULL, *lgeometry = NULL; + gchar *device, *model, *media, *pgeometry = NULL, *lgeometry = NULL; + gchar iface; gint n = 0, i = 0, cache, nn = 0; gchar *capab = NULL, *speed = NULL, *driver = NULL, *ide_storage_list; @@ -305,7 +759,7 @@ void __scan_ide_devices(void) gchar *devid = g_strdup_printf("IDE%d", n); - ide_storage_list = h_strdup_cprintf("$%s$%s=\n", ide_storage_list, devid, model); + ide_storage_list = h_strdup_cprintf("$%s$hd%c=|%s\n", ide_storage_list, devid, iface, model); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, g_str_equal(media, "cdrom") ? "cdrom" : "hdd"); @@ -313,13 +767,8 @@ void __scan_ide_devices(void) gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"), model); - const gchar *url = vendor_get_url(model); - - if (url) { - strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), strhash, vendor_get_name(model), url); - } else { - strhash = h_strdup_cprintf(_("Vendor=%s\n"), strhash, vendor_get_name(model)); - } + strhash = h_strdup_cprintf("$^$%s=%s\n", + strhash, _("Vendor"), model); strhash = h_strdup_cprintf(_("Device Name=hd%c\n" "Media=%s\n" "Cache=%dkb\n"), strhash, iface, media, cache); |