summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2023-07-10 18:43:03 -0400
committerLibravatarUnit 193 <unit193@unit193.net>2023-07-10 18:43:03 -0400
commit6ac681a6f39f057f92f2b52e5b629b235e71ccb1 (patch)
treeb314d0ca4765ff6b02c7f632746de7d8dea11d69
parent2d81a5f58317c43e3b0d230711a6c2cca5fa9c2f (diff)
New upstream version 3.3.28-1.upstream/3.3.28-1
-rwxr-xr-xinxi934
-rw-r--r--inxi.162
-rw-r--r--inxi.changelog227
3 files changed, 997 insertions, 226 deletions
diff --git a/inxi b/inxi
index 9da545d..93ea236 100755
--- a/inxi
+++ b/inxi
@@ -40,6 +40,7 @@ use Getopt::Long qw(GetOptions);
Getopt::Long::Configure ('bundling', 'no_ignore_case',
'no_getopt_compat', 'no_auto_abbrev','pass_through');
use POSIX qw(ceil uname strftime ttyname);
+# use bigint qw/hex/; # to handle large hex number warnings, but Perl 5.010 and later.
# use Benchmark qw(:all);_
# use Devel::Size qw(size total_size);
# use feature qw(say state); # 5.10 or newer Perl
@@ -48,8 +49,8 @@ use POSIX qw(ceil uname strftime ttyname);
## INXI INFO ##
my $self_name='inxi';
-my $self_version='3.3.27';
-my $self_date='2023-05-07';
+my $self_version='3.3.28';
+my $self_date='2023-07-10';
my $self_patch='00';
## END INXI INFO ##
@@ -196,11 +197,11 @@ sub main {
#### -------------------------------------------------------------------
sub initialize {
- set_os();
set_path();
set_user_paths();
set_basics();
set_system_files();
+ set_os();
Configs::set();
# set_downloader();
set_display_size();
@@ -2149,6 +2150,8 @@ sub system_data {
['ipmitool','-V'],# version
['ipmitool','sensor'],
['lscpu',''],# part of util-linux
+ ['lsmem',''],
+ ['lsmem','--all'],
['lspci','--version'],
['lspci',''],
['lspci','-k'],
@@ -2226,6 +2229,7 @@ sub system_files {
'/proc/1/comm',
'/proc/cmdline',
'/proc/cpuinfo',
+ '/proc/iomem',
'/proc/meminfo',
'/proc/modules',
'/proc/net/arp',
@@ -5342,11 +5346,11 @@ sub get {
'fake:s' => sub {
my ($opt,$arg) = @_;
if ($arg){
- my $wl = 'bluetooth|compiler|cpu|dboot|dmidecode|elbrus|ipmi|logical|lspci|';
- $wl .= 'partitions|pciconf|pcictl|pcidump|raid-btrfs|raid-hw|raid-lvm|';
- $wl .= 'raid-md|raid-soft|raid-zfs|sensors|sensors-sys|swaymsg|sysctl|';
- $wl .= 'uptime|usbconfig|usbdevs|vmstat|wl-info|wlr-randr|';
- $wl .= 'xdpyinfo|xorg-log|xrandr';
+ my $wl = 'bluetooth|compiler|cpu|dboot|dmidecode|elbrus|iomem|ipmi|';
+ $wl .= 'logical|lspci|partitions|pciconf|pcictl|pcidump|';
+ $wl .= 'raid-btrfs|raid-hw|raid-lvm|raid-md|raid-soft|raid-zfs|';
+ $wl .= 'sensors|sensors-sys|swaymsg|sys-mem|sysctl|uptime|usbconfig|';
+ $wl .= 'usbdevs|vmstat|wl-info|wlr-randr|xdpyinfo|xorg-log|xrandr';
for (split(',',$arg)){
if ($_ =~ /\b($wl)\b/){
$fake{lc($1)} = 1;
@@ -5788,7 +5792,7 @@ sub show_options {
['1', '-m', '--memory', "Memory (RAM) data. Requires root. Numbers of
devices (slots) supported and individual memory devices (sticks of memory etc).
For devices, shows device locator, type (e.g. DDR3), size, speed. Also shows
- System RAM available/used, and removes Memory report from -I or -tm."],
+ System RAM report, and removes Memory report from -I or -tm."],
['1', '', '--memory-modules,--mm', "Memory (RAM) data. Exclude empty module slots."],
['1', '', '--memory-short,--ms', "Memory (RAM) data. Show only short Memory RAM
report, number of arrays, slots, modules, and RAM type."],
@@ -5992,7 +5996,7 @@ sub show_options {
['2', '-A', '', "Chip vendor:product ID for each audio device; PCIe speed,
lanes (if found); USB rev, speed, lanes (if found); sound server/api helper
daemons/plugins."],
- ['2', '-B', '', "Serial number."],
+ ['2', '-B', '', "Power used, in watts; serial number."],
['2', '-D', '', "Disk transfer speed; NVMe lanes; USB rev, speed, lanes (if
found); Disk serial number; LVM volume group free space (if available); disk
duid (some BSDs)."],
@@ -8322,6 +8326,11 @@ sub battery_output {
main::key($num++,0,2,'charge') => $charge,
main::key($num++,0,2,'condition') => $condition,
});
+ if ($extra > 2){
+ if ($battery->{$key}{'power_now'}){
+ $rows->[$j]{main::key($num++,0,2,'power')} = sprintf('%0.1f W',($battery->{$key}{'power_now'}/10**6));
+ }
+ }
if ($extra > 0 || ($battery->{$key}{'voltage_now'} &&
$battery->{$key}{'voltage_min_design'} &&
($battery->{$key}{'voltage_now'} - $battery->{$key}{'voltage_min_design'}) < 0.5)){
@@ -11357,7 +11366,7 @@ sub cp_cpu_arch {
$model = '' if !defined $model; # model can be 0
my ($arch,$gen,$note,$process,$year);
my $check = main::message('note-check');
- # See: docs/inxi-resources.txt
+ # See: docs/inxi-cpu.txt
# print "type:$type fam:$family model:$model step:$stepping\n";
if ($type eq 'amd'){
if ($family eq '3'){
@@ -12113,6 +12122,12 @@ sub cp_cpu_arch {
$arch = 'Lunar Lake'; # 16 gn
$process = 'Intel 18a (1.8nm)';
$year = '2024+';} # check when actually in production
+ # Meteor Lake-S maybe cancelled, replaced by arrow
+ elsif ($model =~ /^(C6)$/){
+ $arch = 'Arrow Lake'; # 15 gn
+ # gfx tile is TSMC 3nm
+ $process = 'Intel 20a (2nm)';# TSMC 3nm (corei3-5)/Intel 20A 2nm (core i5-9)
+ $year = '2024+';} # check when actually in production
elsif ($model =~ /^(CF)$/){
$arch = 'Emerald Rapids'; # 5th gen xeon
$process = 'Intel 7 (10nm)';
@@ -12124,7 +12139,9 @@ sub cp_cpu_arch {
# Diamond Rapids: Intel 3 (7nm+), 2025
# Raptor Lake: 13 gen, Intel 7 (10nm), 2022
# Meteor Lake: 14 gen, Intel 4 (7nm+)
- # Arrow Lake - 15 gen, Intel 20A (2nm), 2024
+ # Arrow Lake - 15 gen, TSMC 3nm (corei3-5)/Intel 20A 2nm (core i5-9), 2024
+ # Panther Lake - 15 gen, ?
+ # Beast Lake - 15 gen, ?
# Lunar Lake - 16 gen, Intel 18A (1.8nm), 2024-5
# Nova Lake - 17 gen, Intel 18A (1.8nm), 2026
}
@@ -12987,8 +13004,8 @@ sub drive_data {
my ($used) = (0);
PartitionItem::set_partitions() if !$loaded{'set-partitions'};
RaidItem::raid_data() if !$loaded{'raid'};
- # see docs/inxi-data.txt PARTITION DATA for more on remote/fuse fs
- my $fs_skip = PartitionItem::fs_excludes('disk-used');
+ # see docs/inxi-partitions.txt > FILE SYSTEMS for more on remote/fuse fs
+ my $fs_skip = PartitionItem::get_filters('fs-exclude');
foreach my $row (@partitions){
# don't count remote/distributed/union type fs towards used
next if ($row->{'fs'} && $row->{'fs'} =~ /^$fs_skip$/);
@@ -13997,7 +14014,7 @@ sub disk_data_by_id {
}
## START DISK VENDOR BLOCK ##
-# 0: match pattern; 1: replace pattern; 2: vendor print; 3: serial pattern
+# 0 - match pattern; 1 - replace pattern; 2 - vendor print; 3 - serial pattern
sub set_disk_vendors {
eval $start if $b_log;
$vendors = [
@@ -14011,21 +14028,21 @@ sub set_disk_vendors {
['(^MKN|Mushkin)','Mushkin','Mushkin',''], # MKNS
# MU = Multiple_Flash_Reader too risky: |M[UZ][^L] HD103SI HD start risky
# HM320II HM320II HM
- ['(SAMSUNG|^(AWMB|[BC]DS20|[BC]WB|BJ[NT]|[BC]GND|CJN|CUT|[DG]3 Station|DUO\b|DUT|CKT|[GS]2 Portable|GN|HD\d{3}[A-Z]{2}$|(HM|SP)\d{2}|HS\d|M[AB]G\d[FG]|MCC|MCBOE|MCG\d+GC|[CD]JN|MZ|^G[CD][1-9][QS]|P[BM]\d|(SSD\s?)?SM\s?841)|^SSD\s?[89]\d{2}\s(DCT|PRO|QVD|\d+[GT]B)|\bEVO\b|SV\d|[BE][A-Z][1-9]QT|YP\b|[CH]N-M|MMC[QR]E)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
+ ['(SAMSUNG|^(AWMB|[BC]DS20|[BC]WB|BJ[NT]|[BC]GND|CJ[NT]|CUT|[DG]3 Station|DUO\b|DUT|CKT|[GS]2 Portable|GN|HD\d{3}[A-Z]{2}$|(HM|SP)\d{2}|HS\d|M[AB]G\d[FG]|MCC|MCBOE|MCG\d+GC|[CD]JN|MZ|^G[CD][1-9][QS]|P[BM]\d|(SSD\s?)?SM\s?841)|^SSD\s?[89]\d{2}\s(DCT|PRO|QVD|\d+[GT]B)|\bEVO\b|SV\d|[BE][A-Z][1-9]QT|YP\b|[CH]N-M|MMC[QR]E)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
# Android UMS Composite?U1
- ['(SanDisk|0781|^(A[BCD]LC[DE]|AFGCE|D[AB]4|DX[1-9]|Extreme|Firebird|S[CD]\d{2}G|SD(S[S]?[ADQ]|SL\d+G|SU\d)|SDW[1-9]|SE\d{2}|SEM[1-9]|\d[STU]|U(3\b|1\d0))|Clip Sport|Cruzer|iXpand|SSD (Plus|U1[01]0) [1-9]|ULTRA\s(FIT|trek|II)|X[1-6]\d{2})','(SanDisk|0781)','SanDisk',''],
+ ['(SanDisk|0781|^(A[BCD]LC[DE]|AFGCE|D[AB]4|DX[1-9]|Extreme|Firebird|S[CD]\d{2}G|SD(S[S]?[ADQ]|SL\d+G|SU\d|\sUltra)|SDW[1-9]|SE\d{2}|SEM[1-9]|\d[STU]|U(3\b|1\d0))|Clip Sport|Cruzer|iXpand|SSD (Plus|U1[01]0) [1-9]|ULTRA\s(FIT|trek|II)|X[1-6]\d{2})','(SanDisk|0781)','SanDisk',''],
# these are HP/Sandisk cobranded. DX110064A5xnNMRI ids as HP and Sandisc
['(^DX[1-9])','^(HP\b|SANDDISK)','Sandisk/HP',''], # ssd drive, must come before seagate ST test
# real, SSEAGATE Backup+; XP1600HE30002 | 024 HN (spinpoint) ; possible usb: 24AS
# ST[numbers] excludes other ST starting devices
- ['([S]?SEAGATE|^((Barra|Fire)Cuda|BUP|EM\d{3}|Expansion|(ATA\s|HDD\s)?ST\d{2}|5AS|X[AFP])|Expansion Desk|FreeAgent|GoFlex|INIC|Backup(\+|\s?Plus)\s?(Hub)?|OneTouch|Slim\s?BK)','[S]?SEAGATE','Seagate',''],
+ ['([S]?SEAGATE|^((Barra|Fire)Cuda|BUP|EM\d{3}|Expansion|(ATA\s|HDD\s)?ST\d{2}|5AS|X[AFP])|Backup(\+|\s?Plus)\s?(Hub)?|DS2\d|Expansion Desk|FreeAgent|GoFlex|INIC|IronWolf|OneTouch|Slim\s?BK)','[S]?SEAGATE','Seagate',''],
['^(WD|WL[0]9]|Western Digital|My (Book|Passport)|\d*LPCX|Elements|easystore|EA[A-Z]S|EARX|EFRX|EZRX|\d*EAVS|G[\s-]Drive|i HTS|0JD|JP[CV]|MD0|M000|\d+(BEV|(00)?AAK|AAV|AZL|EA[CD]S)|PC\sSN|SPZX|3200[AB]|2500[BJ]|20G2|5000[AB]|6400[AB]|7500[AB]|00[ABL][A-Z]{2}|SSC\b)','(^WDC|Western\s?Digital)','Western Digital',''],
# rare cases WDC is in middle of string
['(\bWDC\b|1002FAEX)','','Western Digital',''],
## THEN BETTER KNOWN ONESs ##
['^Acer','^Acer','Acer',''],
# A-Data can be in middle of string
- ['^(.*\bA-?DATA|ASP\d|AX[MN]|CH11|HV[1-9]|IM2|HD[1-9]|HDD\s?CH|IUM|SX\d|Swordfish)','A-?DATA','A-Data',''],
+ ['^(.*\bA-?DATA|ASP\d|AX[MN]|CH11|FX63|HV[1-9]|IM2|HD[1-9]|HDD\s?CH|IUM|SX\d|Swordfish)','A-?DATA','A-Data',''],
['^(ASUS|ROG)','^ASUS','ASUS',''], # ROG ESD-S1C
# ATCS05 can be hitachi travelstar but not sure
['^ATP','^ATP\b','ATP',''],
@@ -14038,7 +14055,7 @@ sub set_disk_vendors {
['^(DKR|HGST|Touro|54[15]0|7250|HC[CT]\d)','^HGST','HGST (Hitachi)',''], # HGST HUA
['^((ATA\s)?Hitachi|HCS|HD[PST]|DK\d|IC|(HDD\s)?HT|HU|HMS|HDE|0G\d|IHAT)','Hitachi','Hitachi',''],
# vb: VB0250EAVER but clashes with vbox; HP_SSD_S700_120G ;GB0500EAFYL GB starter too generic?
- ['^(HP\b|[MV]B[0-6]|G[BJ]\d|DF\d|F[BK]|0-9]|MM\d{4}|PSS|XR\d{4}|c350|v\d{3}[bgorw]$|x\d{3}[w]$|VK0|HC[CPY]\d|EX9\d\d|VO0)','^HP','HP',''],
+ ['^(HP\b|c350|DF\d|EG0\d{3}|EX9\d\d|G[BJ]\d|F[BK]|0-9]|HC[CPY]\d|MM\d{4}|[MV]B[0-6]|PSS|VO0|VK0|v\d{3}[bgorw]$|x\d{3}[w]$|XR\d{4})','^HP','HP',''],
['^(Lexar|LSD|JumpDrive|JD\s?Firefly|LX\d|WorkFlow)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c; JD Firefly;
# these must come before maxtor because STM
['^STmagic','^STmagic','STmagic',''],
@@ -14093,6 +14110,7 @@ sub set_disk_vendors {
['^Asgard','^Asgard','Asgard',''],
['^(ASM|2115)','^ASM','ASMedia',''],#asm1153e
['^ASolid','^ASolid','ASolid',''],
+ # ASTC (Advanced Storage Technology Consortium)
['^(AVEXIR|AVSSD)','^AVEXIR','Avexir',''],
['^Axiom','^Axiom','Axiom',''],
['^(Baititon|BT\d)','^Baititon','Baititon',''],
@@ -14132,6 +14150,7 @@ sub set_disk_vendors {
['^(Dane-?Elec|Z Mate)','^Dane-?Elec','DaneElec',''],
['^DATABAR','^DATABAR','DataBar',''],
# Daplink vfs is an ARM software thing
+ ['^(Data\s?Memory\s?Systems|DMS)','^Data\s?Memory\s?Systems','Data Memory Systems',''],
['^Dataram','^Dataram','Dataram',''],
['^DELAIHE','^DELAIHE','DELAIHE',''],
# DataStation can be Trekstore or I/O gear
@@ -14191,6 +14210,7 @@ sub set_disk_vendors {
['^(FOXLINE|FLD)','^FOXLINE','Foxline',''], # russian vendor?
['^(GALAX\b|Gamer\s?L|TA\dD|Gamer[\s-]?V)','^GALAX','GALAX',''],
['^Freecom','^Freecom(\sFreecom)?','Freecom',''],
+ ['^(FronTech)','^FronTech','Frontech',''],
['^(Fuhler|FL-D\d{3})','^Fuhler','Fuhler',''],
['^Gaiver','^Gaiver','Gaiver',''],
['^Galaxy\b','^Galaxy','Galaxy',''],
@@ -14198,7 +14218,7 @@ sub set_disk_vendors {
['^(Garmin|Fenix|Nuvi|Zumo)','^Garmin','Garmin',''],
['^Geil','^Geil','Geil',''],
['^GelL','^GelL','GelL',''], # typo for Geil? GelL ZENITH R3 120GB
- ['^(Generic|G1J3|M0S00|SCA\d{2}|SCY|SLD|S0J\d|UY[567])','^Generic','Generic',''],
+ ['^(Generic|A3A|G1J3|M0S00|SCA\d{2}|SCY|SLD|S0J\d|UY[567])','^Generic','Generic',''],
['^(Genesis(\s?Logic)?|05e3)','(Genesis(\s?Logic)?|05e3)','Genesis Logic',''],
['^Geonix','^Geonix','Geonix',''],
['^Getrich','^Getrich','Getrich',''],
@@ -14212,6 +14232,7 @@ sub set_disk_vendors {
['^(Goldkey|GKH\d)','^Goldkey','Goldkey',''],
['^Golden[\s_-]?Memory','^Golden[\s_-]?Memory','Golden Memory',''],
['^(Goldkey|GKP)','^Goldkey','GoldKey',''],
+ ['^(Goline)','^Goline','Goline',''],
# Wilk Elektronik SA, poland
['^(Wilk\s*)?(GOODRAM|GOODDRIVE|IR[\s-]?SSD|IRP|SSDPR|Iridium)','^GOODRAM','GOODRAM',''],
['^(GreatWall|GW\d{3})','^GreatWall','GreatWall',''],
@@ -14224,6 +14245,7 @@ sub set_disk_vendors {
['^(Hajaan|HS[1-9])','^Haajan','Haajan',''],
['^Haizhide','^Haizhide','Haizhide',''],
['^(Hama|FlashPen\s?Fancy)','^Hama','Hama',''],
+ ['^(Hanye|Q60)','^Hanye','Hanye',''],
['^HDC','^HDC\b','HDC',''],
['^Hectron','^Hectron','Hectron',''],
['^HEMA','^HEMA','HEMA',''],
@@ -14235,7 +14257,7 @@ sub set_disk_vendors {
['^Hypertec','^Hypertec','Hypertec',''],
['^HyperX','^HyperX','HyperX',''],
['^(HYSSD|HY-)','^HYSSD','HYSSD',''],
- ['^(Hyundai|Sapphire)','^Hyundai','Hyundai',''],
+ ['^(Hyundai|C2S\d|Sapphire)','^Hyundai','Hyundai',''],
['^(IBM|DT|ESA[1-9]|ServeRaid)','^IBM','IBM',''], # M5110 too common
['^IEI Tech','^IEI Tech(\.|nology)?( Corp(\.|oration)?)?','IEI Technology',''],
['^(IGEL|UD Pocket)','^IGEL','IGEL',''],
@@ -14248,7 +14270,7 @@ sub set_disk_vendors {
['^(Infokit)','^Infokit','Infokit',''],
# note: Initio default controller, means master/slave jumper is off/wrong, not a vendor
['^Inland','^Inland','Inland',''],
- ['^(InnoDisk|Innolite|SATA\s?Slim|DRPS)','^InnoDisk( Corp.)?','InnoDisk',''],
+ ['^(InnoDisk|DEM\d|Innolite|SATA\s?Slim|DRPS)','^InnoDisk( Corp.)?','InnoDisk',''],
['(Innostor|1f75)','(Innostor|1f75)','Innostor',''],
['(^Innovation|Innovation\s?IT)','Innovation(\s*IT)?','Innovation IT',''],
['^Innovera','^Innovera','Innovera',''],
@@ -14295,7 +14317,7 @@ sub set_disk_vendors {
['^KLLISRE','^KLLISRE','KLLISRE',''],
['(KIOXIA|^K[BX]G\d)','KIOXIA','KIOXIA',''], # company name comes after product ID
['^(KLEVV|NEO\sN|CRAS)','^KLEVV','KLEVV',''],
- ['^Kodak','^Kodak','Kodak',''],
+ ['^(Kodak|Memory\s?Saver)','^Kodak','Kodak',''],
['^(KOOTION)','^KOOTION','KOOTION',''],
['^(KUAIKAI|MSAM)','^KUAIKAI','KuaKai',''],
['(KUIJIA|DAHUA)','^KUIJIA','KUIJIA',''],
@@ -14312,6 +14334,7 @@ sub set_disk_vendors {
['^RPFT','','Lenovo O.E.M.',''],
# JAJS300M120C JAJM600M256C JAJS600M1024C JAJS600M256C JAJMS600M128G
['^(Leven|JAJ[MS])','^Leven','Leven',''],
+ ['^(LEQIXIANG)','^LEQIXIANG','Leqixiang',''],
['^(LG\b|Xtick)','^LG','LG',''],
['(LITE[-\s]?ON[\s-]?IT)','LITE[-]?ON[\s-]?IT','LITE-ON IT',''], # LITEONIT_LSS-24L6G
# PH6-CE240-L; CL1-3D256-Q11 NVMe LITEON 256GB
@@ -14389,6 +14412,7 @@ sub set_disk_vendors {
['^Pioneer','Pioneer','Pioneer',''],
['^Platinet','Platinet','Platinet',''],
['^(PLEXTOR|PX-)','^PLEXTOR','Plextor',''],
+ ['^(Polion)','^Polion','Polion',''],
['^(PQI|Intelligent\s?Stick|Cool\s?Drive)','^PQI','PQI',''],
['^(Premiertek|QSSD|Quaroni)','^Premiertek','Premiertek',''],
['^(-?Pretec|UltimateGuard)','-?Pretec','Pretec',''],
@@ -14397,6 +14421,7 @@ sub set_disk_vendors {
['^PUSKILL','^PUSKILL','Puskill',''],
['QEMU','^\d*QEMU( QEMU)?','QEMU',''], # 0QUEMU QEMU HARDDISK
['(^Quantum|Fireball)','^Quantum','Quantum',''],
+ ['(^QOOTEC|QMT)','^QOOTEC','QOOTEC',''],
['^QUMO','^QUMO','Qumo',''],
['^Qunion','^Qunion','Qunion',''],
['^(R[3-9]|AMD\s?(RADEON)?|Radeon)','AMD\s?(RADEON)?','AMD Radeon',''], # ssd
@@ -14465,11 +14490,13 @@ sub set_disk_vendors {
['^TEAC','^TEAC','TEAC',''],
['^(TEAM|T[\s-]?Create|L\d\s?Lite|T\d{3,}[A-Z]|TM\d|(Dark\s?)?L3\b|T[\s-]?Force)','^TEAM(\s*Group)?','TeamGroup',''],
['^(Teclast|CoolFlash)','^Teclast','Teclast',''],
+ ['^(tecmiyo)','^tecmiyo','TECMIYO',''],
['^Teelkoou','^Teelkoou','Teelkoou',''],
['^Tele2','^Tele2','Tele2',''],
['^Teleplan','^Teleplan','Teleplan',''],
['^TEUTONS','^TEUTONS','TEUTONS',''],
['^(Textorm)','^Textorm','Textorm',''], # B5 too short
+ ['^(T(&|\s?and\s?)?G\d{3})','^T&G\b','T&G',''],
['^THU','^THU','THU',''],
['^Tiger[\s_-]?Jet','^Tiger[\s_-]?Jet','TigerJet',''],
['^Tigo','^Tigo','Tigo',''],
@@ -14493,6 +14520,7 @@ sub set_disk_vendors {
['^(USBest|UT16)','^USBest','USBest',''],
['^(OOS[1-9]|Utania)','Utania','Utania',''],
['^U-TECH','U-TECH','U-Tech',''],
+ ['^(Value\s?Tech|VTP\d)','^Value\s?Tech','ValueTech',''],
['^VBOX','','VirtualBox',''],
['^(Veno|Scorp)','^Veno','Veno',''],
['^(Verbatim|STORE\s?\'?N\'?\s?(FLIP|GO)|Vi[1-9]|OTG\s?Tiny)','^Verbatim','Verbatim',''],
@@ -14512,6 +14540,7 @@ sub set_disk_vendors {
['^Wilk','^Wilk','Wilk',''],
['^(WinMemory|SWG\d)','^WinMemory','WinMemory',''],
['^(Winton|WT\d{2})','^Winton','Winton',''],
+ ['^(WISE)','^WISE','WISE',''],
['^WPC','^WPC','WPC',''], # WPC-240GB
['^(Wortmann(\sAG)?|Terra\s?US)','^Wortmann(\sAG)?','Wortmann AG',''],
['^(XDisk|X9\b)','^XDisk','XDisk',''],
@@ -14555,7 +14584,7 @@ sub disk_vendor {
# 0 - match pattern; 1 - replace pattern; 2 - vendor print; 3 - serial pattern
# Data URLs: inxi-resources.txt Section: DriveItem device_vendor()
# $model = 'H10 HBRPEKNX0202A NVMe INTEL 512GB';
- # $model = 'Patriot Memory';
+ # $model = 'SD Ultra 3D 1TB';
set_disk_vendors() if !$vendors;
# prefilter this one, some usb enclosurs and wrong master/slave hdd show default
$model =~ s/^Initio[\s_]//i;
@@ -16977,7 +17006,7 @@ sub set_amd_data {
'years' => '2020-22',
},
{'arch' => 'RDNA-3',
- 'ids' => '73a8|7448|744c|745e|7480|7483',
+ 'ids' => '73a8|73f0|7448|744c|745e|7480|7483|7489',
'code' => 'Navi-3x',
'process' => 'TSMC n5 (5nm)',
'years' => '2022+',
@@ -17161,7 +17190,8 @@ sub set_intel_data {
},
# Jupiter Sound cancelled?
{'arch' => 'Gen-12.7',
- 'ids' => '5690|5691|5692|5693|5694|56a0|56a1|56a5|56a6',
+ 'ids' => '5690|5691|5692|5693|5694|5698|56a0|56a1|56a3|56a4|56a5|56a6|56a7|' .
+ '56a8|56a9',
'code' => 'Alchemist',
'process' => 'TSMC n6 (7nm)',
'years' => '2022+',
@@ -17179,6 +17209,13 @@ sub set_intel_data {
'process' => 'Intel 7 (10nm)',
'years' => '2022+',
},
+ {'arch' => 'Gen-14',
+ 'ids' => '7d40|7d45|7d55|7d60|7dd5',
+ 'code' => '',
+ 'process' => 'Intel 4 (7nm+)',
+ 'years' => '2023+',
+ },
+
];
}
@@ -17393,7 +17430,7 @@ sub set_nv_data {
'legacy' => 0,
'process' => 'TSMC 28nm',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2014-19',
@@ -17410,7 +17447,7 @@ sub set_nv_data {
'legacy' => 0,
'process' => 'TSMC 16nm',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2016-21',
@@ -17423,7 +17460,7 @@ sub set_nv_data {
'legacy' => 0,
'process' => 'TSMC 12nm',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2017-20',
@@ -17434,13 +17471,13 @@ sub set_nv_data {
'1f07|1f08|1f0a|1f0b|1f10|1f11|1f12|1f14|1f15|1f36|1f42|1f47|1f50|1f51|1f54|' .
'1f55|1f76|1f82|1f83|1f91|1f95|1f96|1f97|1f98|1f99|1f9c|1f9d|1f9f|1fa0|1fb0|' .
'1fb1|1fb2|1fb6|1fb7|1fb8|1fb9|1fba|1fbb|1fbc|1fdd|1ff0|1ff2|1ff9|2182|2184|' .
- '2187|2188|2189|2191|2192|21c4|21d1|25a6|25a7|25a9|25aa|25ad|25ed',
+ '2187|2188|2189|2191|2192|21c4|21d1|25a6|25a7|25a9|25aa|25ad|25ed|28b8',
'code' => 'TUxxx',
'kernel' => '',
'legacy' => 0,
'process' => 'TSMC 12nm FF',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2018-22',
@@ -17449,15 +17486,15 @@ sub set_nv_data {
'ids' => '20b0|20b2|20b3|20b5|20b7|20f1|20f3|20f5|2203|2204|2206|2207|2208|' .
'220a|220d|2216|2230|2231|2232|2233|2235|2236|2237|2238|2414|2420|2438|2460|' .
'2482|2484|2486|2487|2488|2489|248a|249c|249d|24a0|24b0|24b1|24b6|24b7|24b8|' .
- '24b9|24ba|24bb|24c9|24dc|24dd|24e0|24fa|2503|2504|2507|2508|2520|2521|2523|' .
- '2531|2544|2560|2563|2571|2582|25a0|25a2|25a5|25ab|25ac|25b6|25b8|25b9|25ba|' .
- '25bb|25e0|25e2|25e5|25ec|25f9|25fa|25fb',
+ '24b9|24ba|24bb|24c7|24c9|24dc|24dd|24e0|24fa|2503|2504|2507|2508|2520|2521|' .
+ '2523|2531|2544|2560|2563|2571|2582|25a0|25a2|25a5|25ab|25ac|25b6|25b8|25b9|' .
+ '25ba|25bb|25bc|25bd|25e0|25e2|25e5|25ec|25f9|25fa|25fb|2838',
'code' => 'GAxxx',
'kernel' => '',
'legacy' => 0,
'process' => 'TSMC n7 (7nm)',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2020-22',
@@ -17469,20 +17506,20 @@ sub set_nv_data {
'legacy' => 0,
'process' => 'TSMC n4 (5nm)',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2022+',
},
{'arch' => 'Lovelace',
- 'ids' => '2684|26b1|26b5|2704|2717|2757|2782|27a0|27b8|27e0|2820|2860|28a0|' .
- '28a1|28e0|28e1',
+ 'ids' => '2684|26b1|26b5|2704|2717|2757|2782|2786|27a0|27b8|27e0|2803|2820|' .
+ '2860|28a0|28a1|28e0|28e1',
'code' => 'AD1xx',
'kernel' => '',
'legacy' => 0,
'process' => 'TSMC n4 (5nm)',
'release' => '',
- 'series' => '530.xx+',
+ 'series' => '535.xx+',
'status' => $status_current,
'xorg' => '',
'years' => '2022-23+',
@@ -18375,7 +18412,9 @@ sub component_recursive_data {
}
## MachineItem
+# Public: get(), is_vm()
{
+my $b_vm;
package MachineItem;
sub get {
@@ -18456,6 +18495,10 @@ sub get {
return $rows;
}
+sub is_vm {
+ return $b_vm;
+}
+
## keys for machine data are:
# 0: sys_vendor; 1: product_name; 2: product_version; 3: product_serial;
# 4: product_uuid; 5: board_vendor; 6: board_name; 7: board_version;
@@ -18719,7 +18762,7 @@ sub machine_data_sys {
}
if ($data->{'chassis_type'}){
if ($data->{'chassis_type'} == 1){
- $data->{'device'} = get_device_vm($data->{'sys_vendor'},$data->{'product_name'});
+ $data->{'device'} = check_vm($data->{'sys_vendor'},$data->{'product_name'});
$data->{'device'} ||= 'other-vm?';
}
else {
@@ -18933,6 +18976,7 @@ sub machine_data_dmi {
if (!$data->{'device'}){
if (grep {/hypervisor/i} @$row){
$data->{'device'} = 'virtual-machine';
+ $b_vm = 1;
}
}
last;
@@ -18942,7 +18986,7 @@ sub machine_data_dmi {
}
}
if (!$data->{'device'}){
- $data->{'device'} = get_device_vm($data->{'sys_vendor'},$data->{'product_name'});
+ $data->{'device'} = check_vm($data->{'sys_vendor'},$data->{'product_name'});
$data->{'device'} ||= 'other-vm?';
}
# print "dmi:\n";
@@ -19030,7 +19074,7 @@ sub machine_data_sysctl {
$product = $data->{'board_name'} if !$product;
}
# detections can be from other sources.
- $data->{'device'} = get_device_vm($vendor,$product);
+ $data->{'device'} = check_vm($vendor,$product);
print Data::Dumper::Dumper $data if $dbg[28];
main::log_data('dump','%data',$data) if $b_log;
eval $end if $b_log;
@@ -19086,7 +19130,7 @@ sub get_device_sys {
return $device;
}
-sub get_device_vm {
+sub check_vm {
eval $start if $b_log;
my ($manufacturer,$product_name) = @_;
$manufacturer ||= '';
@@ -19175,6 +19219,7 @@ sub get_device_vm {
if (!$vm && $manufacturer && $manufacturer eq 'Xen'){
$vm = 'xen';
}
+ $b_vm = 1 if $vm;
eval $end if $b_log;
return $vm;
}
@@ -20081,6 +20126,8 @@ sub drive_data_linux {
## PartitionItem
{
+# these will be globally accessible via PartitionItem::filters()
+my ($fs_exclude,$fs_skip,$part_filter);
package PartitionItem;
sub get {
@@ -20089,7 +20136,7 @@ sub get {
my $rows = [];
my $num = 0;
set_partitions() if !$loaded{'set-partitions'};
- # fails in corner case with zram but no other mounted filesystems
+ # Fails in corner case with zram but no other mounted filesystems
if (!@partitions){
$key1 = 'Message';
#$val1 = ($bsd_type && $bsd_type eq 'darwin') ?
@@ -20117,7 +20164,7 @@ sub create_output {
else {
@partitions = sort { $a->{$show{'partition-sort'}} <=> $b->{$show{'partition-sort'}} } @partitions;
}
- my $fs_skip = fs_excludes('label-uuid');
+ my $fs_skip = get_filters('fs-skip');
foreach my $row (@partitions){
$num = 1;
next if $row->{'type'} eq 'secondary' && $show{'partition'};
@@ -20163,8 +20210,8 @@ sub create_output {
}
if ($b_admin && $row->{'block-size'}){
$rows->[$j]{main::key($num++,0,2,'block-size')} = $row->{'block-size'} . ' B';;
- #$rows->[$j]{main::key($num++,0,2,'physical')} = $row->{'block-size'} . ' B';
- #$rows->[$j]{main::key($num++,0,2,'logical')} = $row->{'block-logical'} . ' B';
+ # $rows->[$j]{main::key($num++,0,2,'physical')} = $row->{'block-size'} . ' B';
+ # $rows->[$j]{main::key($num++,0,2,'logical')} = $row->{'block-logical'} . ' B';
}
$rows->[$j]{main::key($num++,1,2,$dev_type)} = $dev;
if ($b_admin && $row->{'maj-min'}){
@@ -20192,7 +20239,7 @@ sub create_output {
}
}
}
- # corner case, no partitions, but zram swap
+ # Corner case, no partitions, but zram swap.
if (!@$rows){
@$rows = ({main::key($num++,0,1,'Message') => main::message('partition-data')});
}
@@ -20201,7 +20248,7 @@ sub create_output {
sub set_partitions {
eval $start if $b_log;
- #return if $bsd_type && $bsd_type eq 'darwin'; # darwin has muated output, of course
+ # return if $bsd_type && $bsd_type eq 'darwin'; # darwin has mutated output
my (@data,@rows,@mount,@partitions_working,$part,@working);
my ($back_size,$back_used,$b_fs,$cols) = (4,3,1,6);
my ($b_dfp,$b_fake_map,$b_load,$b_logical,$b_space,);
@@ -20210,18 +20257,22 @@ sub set_partitions {
$type,$uuid,$used);
$loaded{'set-partitions'} = 1;
if ($b_admin){
- # for partition block size
+ # For partition block size
$blockdev = $alerts{'blockdev'}->{'path'} if $alerts{'blockdev'}->{'path'};
}
- # for raw partition sizes, maj_min
- PartitionData::set() if !$bsd_type && !$loaded{'partition-data'};
- DiskDataBSD::set() if $bsd_type && !$loaded{'disk-data-bsd'};
- LsblkData::set() if !$bsd_type && !$loaded{'lsblk'};
+ # For raw partition sizes, maj_min
+ if ($bsd_type){
+ DiskDataBSD::set() if !$loaded{'disk-data-bsd'};
+ }
+ else {
+ PartitionData::set() if !$loaded{'partition-data'};
+ LsblkData::set() if !$loaded{'lsblk'};
+ }
# set @labels, @uuid
if (!$bsd_type){
set_label_uuid() if !$loaded{'label-uuid'};
}
- # most current OS support -T and -k, but -P means different things
+ # Most current OS support -T and -k, but -P means different things
# in freebsd. However since most use is from linux, we make that default
# android 7 no -T support
if (!$fake{'partitions'}){
@@ -20230,9 +20281,9 @@ sub set_partitions {
$b_dfp = 1;
}
elsif (@partitions_working = main::grabber("df -T -k 2>/dev/null")){
- # fine, it worked, could be bsd or linux
+ # Fine, it worked, could be bsd or linux
}
- # busybox supports -k and -P, older openbsd, darwin, solaris don't have -P
+ # Busybox supports -k and -P, older openbsd, darwin, solaris don't have -P
else {
if (@partitions_working = main::grabber("df -k -P 2>/dev/null")){
$b_dfp = 1;
@@ -20253,7 +20304,7 @@ sub set_partitions {
@partitions_working = main::reader($file);
}
# print Data::Dumper::Dumper \@partitions_working;
- # determine positions
+ # Determine positions
if (@partitions_working){
my $row1 = shift @partitions_working;
$row1 =~ s/Mounted on/Mounted-on/i;
@@ -20279,9 +20330,10 @@ sub set_partitions {
@partitions_working = @part_temp;
}
if (!$bsd_type){
- # new kernels/df have rootfs and / repeated, creating two entries for the same partition
- # so check for two string endings of / then slice out the rootfs one, I could check for it
- # before slicing it out, but doing that would require the same action twice re code execution
+ # New kernels/df have rootfs and / repeated, creating two entries for the
+ # same partition so check for two string endings of / then slice out the
+ # rootfs one, I could check for it before slicing it out, but doing that
+ # would require the same action twice re code execution.
my $roots = 0;
foreach (@partitions_working){
$roots++ if /\s\/$/;
@@ -20298,7 +20350,12 @@ sub set_partitions {
($back_size,$back_used) = (7,6);
}
}
- my $filters = partition_filters();
+ my $filters = get_filters('partition');
+ # These are local, not remote, iso, or overlay types:
+ my $fuse_fs = 'adb|apfs(-?fuse)?|archive(mount)?|gphoto|gv|gzip|ifuse|';
+ $fuse_fs .= '[^\.]*mtp|ntfs-?3g|[^\.]*ptp|vdfuse|vram|wim(mount)?|xb|xml';
+ # Just the common ones desktops might have
+ my $remote_fs = 'curlftp|gmail|g(oogle-?)?drive|pnfs|\bnfs|rclone|s3fs|smb|ssh';
# push @partitions_working, '//mafreebox.freebox.fr/Disque dur cifs 239216096 206434016 20607496 91% /freebox/Disque dur';
# push @partitions_working, '//mafreebox.freebox.fr/AllPG cifs 436616192 316339304 120276888 73% /freebox/AllPG';
# push(@partitions_working,'/dev/loop0p1 iso9660 3424256 3424256 0 100% /media/jason/d-live nf 11.3.0 gn 6555 9555 amd64');
@@ -20328,7 +20385,7 @@ sub set_partitions {
# print Data::Dumper::Dumper \@row;
$row[0] =~ s/\^\^/ /g if $b_space; # reset spaces in > 1 word fs name
# autofs is a bsd thing, has size 0
- if ($row[0] =~ /^($filters)$/ || $row[0] =~ /^ROOT/i ||
+ if ($row[0] =~ /^$filters$/ || $row[0] =~ /^ROOT/i ||
($b_fs && ($row[2] == 0 || $row[1] =~ /^(autofs|devtmpfs|iso9660|tmpfs)$/))){
next;
}
@@ -20442,19 +20499,26 @@ sub set_partitions {
$dev_base = $1;
}
# note: possible: sshfs path: beta:data/; remote: fuse.rclone
- elsif ($dev_base =~ /^\/\/|:\// || ($fs && $fs =~ /(rclone)/)){
+ elsif ($dev_base =~ /^\/\/|:\// || ($fs && $fs =~ /($remote_fs)/i)){
$dev_type = 'remote';
$dev_base = $row[0] if !$dev_base; # only trips in fs test case
}
# a slice bsd system, zfs can't be detected this easily
- elsif ($b_logical && $fs && $fs =~ /^(null(fs)?)$/){
+ elsif ($b_logical && $fs && $fs =~ /^null(fs)?$/){
$dev_type = 'logical';
$dev_base = $row[0] if !$dev_base;
}
- # an error has occurred almost for sure
elsif (!$dev_base){
- $dev_type = 'source';
- $dev_base = main::message('unknown-dev');
+ if ($fs && $fs =~ /^(fuse[\._-]?)?($fuse_fs)(fs)?/i){
+ $dev_base = $2;
+ $dev_type = 'fuse';
+ }
+ # Check dm-crypt, that may be real partition type, but no data.
+ # We've hit something inxi doesn't know about, or error has occured
+ else {
+ $dev_type = 'source';
+ $dev_base = main::message('unknown-dev');
+ }
}
else {
$dev_type = 'dev';
@@ -20642,12 +20706,12 @@ sub swap_advanced_data {
sub check_partition_data {
eval $start if $b_log;
my ($b_found,$dev_mapped,$temp);
- my $filters = partition_filters();
+ my $filters = get_filters('partition');
foreach my $row (@lsblk){
$b_found = 0;
$dev_mapped = '';
if (!$row->{'name'} || !$row->{'mount'} || !$row->{'type'} ||
- ($row->{'fs'} && $row->{'fs'} =~ /^($filters)$/) ||
+ ($row->{'fs'} && $row->{'fs'} =~ /^$filters$/) ||
($row->{'type'} =~ /^(disk|loop|rom)$/)){
next;
}
@@ -20692,38 +20756,72 @@ sub check_partition_data {
eval $end if $b_log;
}
-# NOTE: Was forgetting to update one or the other so put them
-# all here for: subs partitiion_data(), check_partition_data()
-# note: p_d filters 'filesystem', and c_p_d filters against fs
-sub partition_filters {
- # snap mounts with squashfs; appimage/flatpak mount?
- # swap is set in swap_data(); cgmfs is in ram, like devfs, sysfs;
- # union fs types: aufs, lofs, overlayfs, unionfs, mergerfs
- my $filters = 'aufs|cgroup.*|cgmfs|configfs|debugfs|\/dev|dev|\/dev\/loop[0-9]*|';
- $filters .= 'devfs|devtmpfs|efivarfs|fdescfs|hugetlbfs|iso9660|kernfs|';
- $filters .= 'linprocfs|linsysfs|lofs|mergerfs|none|overla(id|y)(fs)?|procfs|';
- $filters .= 'ptyfs|/run(\/.*)?|run|securityfs|shm|squashfs|swap|';
- $filters .= 'sys|\/sys\/.*|sysfs|tmpfs|tracefs|type|udev|unionfs|vartmp';
- return $filters
-}
-
-# Used to exclude disk used, partition/unmounted/swap label/uuid, unmounted label/uuid
-# see docs/inxi-data.txt PARTITION DATA for more on remote/fuse fs
-sub fs_excludes {
- my ($source) = @_;
- # panfs is parallel NAS volume manager, need more data
- # null is hammer fs slice; nfs/nfs3/nfs4; some can be fuse mounts: fuse.sshfs
- # afs aufs avfs cifs ffs gfs\d{0,2} hdfs ipfs k(osmos)?fs .*lafs lofs mhddfs
- # mergerfs nfs\d{0,2} null ocfs\d{0,2} openafs orangefs overla(id|y)(fs)?
- # panfs pvfs\d{0,2} s3fs squashfs sshfs smbfs unionfs vmfs
- my $excludes = '(fuse(blk)?[\._-]?)?(';
- $excludes .= 'f|' if $source eq 'label-uuid'; # ffs not remote, but no u/l
- $excludes .= 'a|archivemount|au|av|ceph|ci|g|gluster|gmail|hd|ip|';
- $excludes .= 'iso9660|k(osmos)?|lo|.*la|mhdd|merger|moose|n|null|oc|opena|';
- $excludes .= 'orange|overla(id|y)|pan|pv|s3|rclone|sheepdog|squash|ssh|';
- $excludes .= 'smb|union|vm';
- $excludes .= ')(fs)?(\d{0,2})?';
- return $excludes;
+# fs-exclude: Excludes fs size from disk used total;
+# fs-skip: do not display label/uuid fields from partition/unmounted/swap.
+# partition: do not use this partition in -p output.
+# args: 0: [fs-exclude|fs-skip|partition]
+sub get_filters {
+ set_filters() if !$fs_exclude;
+ if ($_[0] eq 'fs-exclude'){
+ return $fs_exclude;
+ }
+ elsif ($_[0] eq 'fs-skip'){
+ return $fs_skip;
+ }
+ elsif ($_[0] eq 'partition'){
+ return $part_filter;
+ }
+}
+
+# See docs/inxi-partitions.txt FILE SYSTEMS for specific fs info.
+# The filter string must match /^[regex]$/ exactly.
+sub set_filters {
+ # Notes: appimage/flatpak mount?; astreamfs reads remote http urls;
+ # avfs == fuse; cgmfs,vramfs in ram, like devfs, sysfs; gfs = googlefs;
+ # hdfs == hadoop; ifs == integrated fs; pvfs == orangefs; smb == cifs;
+ # null == hammer fs slice; kfs/kosmosfs == CloudStore;
+ # snap mounts with squashfs; swap is set in swap_data(); vdfs != vdfuse;
+ # vramfs == like zram except gpu ram;
+ # Some can be fuse mounts: fuse.sshfs.
+ # Distributed/Remote: 9p, (open-)?afs, alluxio, astreamfs, beegfs,
+ # cephfs, cfs, chironfs, cifs, cloudstore, dfs, davfs, dce,
+ # gdrivefs, gfarm, gfs\d{0,2}, gitfs, glusterfs, gmailfs, gpfs,
+ # hdfs, httpdirfs, hubicfuse, ipfs, juice, k(osmos)?fs, .*lafs, lizardfs,
+ # lustre, magma, mapr, moosefs, nfs[34], objective, ocfs\d{0,2}, onefs,
+ # orangefs, panfs, pnfs, pvfs\d{0,2}, rclone, restic, rozofs, s3fs, scality,
+ # sfs, sheepdogfs, spfs, sshfs, smbfs, v9fs, vdfs, vmfs, xtreemfs
+ # Stackable/Union: aufs, e?cryptfs, encfs, erofs, gocryptfs, ifs, lofs,
+ # mergerfs, mhddfs, overla(id|y)(fs)?, squashfs, unionfs;
+ # ISO/Archive: archive(mount)?, atlas, avfs. borg, erofs, fuse-archive,
+ # fuseiso, gzipfs, iso9660, lofs, vdfuse, wimmountfs, xbfuse
+ # FUSE: adbfs, apfs-fuse, gvfs, gvfs-mtp, ifuse, jmtpfs, mtpfs, ptpfs,
+ # simple-mtpfs, vramfs, xmlfs
+ # System fs: cgmfs, configfs, debugfs, devfs, devtmpfs, efivarfs, fdescfs,
+ # hugetlbfs, kernfs, linprocfs, linsysfs, lxcfs, procfs, ptyfs, run,
+ # securityfs, shm, swap, sys, sysfs, tmpfs, tracefs, type, udev, vartmp
+ # System dir: /dev, /dev/loop[0-9]+, /run(/.*)?, /sys/.*
+
+ ## These are global, all filters use these. ISO, encrypted/stacked
+ my @all = qw%au av e?crypt enc ero gocrypt i (fuse-?)?iso iso9660 lo merger
+ mhdd overla(id|y) splitview(-?fuse)? squash union xbfuse%;
+ ## These are fuse/archive/distributed/remote/clustered mostly
+ my @exclude = (@all,qw%9p (open-?)?a adb archive(mount)? astream atlas
+ beeg borg c ceph chiron ci cloudstore curlftp d dav dce
+ g gdrive gfarm git gluster gmail gocrypt google-drive-ocaml gp gphoto gv gzip
+ hd httpd hubic ip juice k(osmos)? .*la lizard lustre magma mapr moose .*mtp
+ null p?n objective oc one orange pan .*ptp pv rclone restic rozo
+ s s3 scality sheepdog sp ssh smb v9 vd vm vram wim(mount)? xb xml xtreem%);
+ # Various RAM based system FS
+ my @partition = (@all,qw%cgroup.* cgm config debug dev devtmp efivar fdesc
+ hugetlb kern linproc linsys lxc none proc pty run security shm swap sys
+ tmp trace type udev vartmp%);
+ my $start = '(fuse(blk)?[\._-]?)?(';
+ my $end = ')([\._-]?fuse)?(fs)?\d{0,2}';
+ $fs_exclude = $start . join('|',@exclude) . $end;
+ $fs_skip = $start . join('|',@exclude,'f') . $end; # apfs?; BSD ffs has no u/l
+ $part_filter = '((' . join('|',@partition) . ')(fs)?|';
+ $part_filter .= '\/dev|\/dev\/loop[0-9]+|\/run(\/.*)?|\/sys\/.*)';
+ # print "$part_filter\n";
}
sub get_mounts_fs {
@@ -20971,7 +21069,12 @@ sub mem_processes {
}
@ps_rows = splice(@ps_rows,0,$count);
# print Data::Dumper::Dumper \@rows;
- push(@$rows,main::MemoryData::row('process')) if !$loaded{'memory'};
+ if (!$loaded{'memory'}){
+ my $row = {};
+ main::MemoryData::row('process',$row,\$num,1);
+ push(@$rows,$row);
+ $num = 0;
+ }
$j = scalar @$rows;
my $throttled = throttled($ps_count,$count,$j);
#$cpu_mem = ' - CPU: % used' if $extra > 0;
@@ -22295,12 +22398,11 @@ sub check_zfs_status {
{
package RamItem;
my ($vendors,$vendor_ids);
-
+my $ram_total = 0;
sub get {
my ($key1,$ram,$val1);
my $rows = [];
my $num = 0;
- push(@$rows, MemoryData::row('ram')) if !$loaded{'memory'};
if ($bsd_type && !$force{'dmidecode'} && ($dboot{'ram'} || $fake{'dboot'})){
$ram = dboot_data();
if (@$ram){
@@ -22337,11 +22439,22 @@ sub get {
main::key($num++,0,2,$key1) => $val1,
});
}
+ # we want the real installed RAM total if detected so add this after.
+ if (!$loaded{'memory'}){
+ $num = 0;
+ my $system_ram = {};
+ MemoryData::row('ram',$system_ram,\$num,1);
+ unshift(@$rows,$system_ram);
+ }
($vendors,$vendor_ids) = ();
eval $end if $b_log;
return $rows;
}
+sub ram_total {
+ return $ram_total;
+}
+
sub ram_output {
eval $start if $b_log;
my ($rows,$ram,$source) = @_;
@@ -22367,11 +22480,16 @@ sub ram_output {
if ($item->{'cap-qualifier'}){
$rows->[$j]{main::key($num++,0,3,'note')} = $item->{'cap-qualifier'};
}
+ # show if > 1 array otherwise shows in System RAM line.
+ if (scalar @$ram > 1){
+ $rows->[$j]{main::key($num++,0,2,'installed')} = process_size($item->{'used-capacity'});
+ }
$rows->[$j]{main::key($num++,0,2,'use')} = $item->{'use'} if $b_non_system;
$rows->[$j]{main::key($num++,1,2,'slots')} = $item->{'slots'};
if ($item->{'slots-qualifier'}){
$rows->[$j]{main::key($num++,0,3,'note')} = $item->{'slots-qualifier'};
}
+ $rows->[$j]{main::key($num++,0,2,'modules')} = $item->{'slots-active'};
$item->{'eec'} ||= 'N/A';
$rows->[$j]{main::key($num++,0,2,'EC')} = $item->{'eec'};
if ($extra > 0 && (!$b_non_system ||
@@ -22521,7 +22639,8 @@ sub ram_output {
sub dmidecode_data {
eval $start if $b_log;
my ($b_5,$handle,@temp);
- my ($derived_module_size,$max_cap_5,$max_cap_16,$max_module_size) = (0,0,0,0);
+ my ($derived_module_size,$max_cap_5,$max_cap_16,$max_module_size,
+ $slots_active) = (0,0,0,0,0);
my ($i,$j,$k) = (0,0,0);
my $ram = [];
my $check = main::message('note-check');
@@ -22530,6 +22649,7 @@ sub dmidecode_data {
## Note: do NOT reset these values, that causes failures
# ($derived_module_size,$max_cap_5,$max_cap_16,$max_module_size) = (0,0,0,0);
if ($entry->[0] == 5){
+ $slots_active = 0;
foreach my $item (@$entry){
@temp = split(/:\s*/, $item, 2);
next if !$temp[1];
@@ -22575,6 +22695,7 @@ sub dmidecode_data {
$temp[1] =~ s/ Connection\)?//;
$temp[1] =~ s/^[0-9]+\s*[KkMGTP]B\s*\(?//;
$type = lc($temp[1]);
+ $slots_active++;
}
elsif ($temp[0] eq 'Current Speed'){
$speed = main::clean_dmi($temp[1]);
@@ -22614,6 +22735,7 @@ sub dmidecode_data {
$handle = $entry->[1];
$ram->[$handle] = $ram->[$k] if $ram->[$k];
$ram->[$k] = undef;
+ $slots_active = 0;
# ($derived_module_size,$max_cap_16) = (0,0);
foreach my $item (@$entry){
@temp = split(/:\s*/, $item, 2);
@@ -22678,6 +22800,7 @@ sub dmidecode_data {
$derived_module_size = calculate_size($temp[1],$derived_module_size);
$working_size = calculate_size($temp[1],0);
$device_size = $working_size;
+ $slots_active++;
}
else {
$device_size = $temp[1];
@@ -22781,6 +22904,7 @@ sub dmidecode_data {
}
}
$ram->[$handle]{'derived-module-size'} = $derived_module_size;
+ $ram->[$handle]{'slots-active'} = $slots_active;
$ram->[$handle]{'modules'}[$i]{'configured-clock-speed'} = $configured_speed;
$ram->[$handle]{'modules'}[$i]{'configured-note'} = $configured_note if $configured_note;
$ram->[$handle]{'modules'}[$i]{'data-width'} = $data_width;
@@ -22808,11 +22932,11 @@ sub dmidecode_data {
last;
}
}
- print Data::Dumper::Dumper $ram if $dbg[36];
+ print 'dmidecode pre process_data: ', Data::Dumper::Dumper $ram if $dbg[36];
main::log_data('dump','@$ram',$ram) if $b_log;
process_data($ram) if @$ram;
main::log_data('dump','@$ram',$ram) if $b_log;
- print Data::Dumper::Dumper $ram if $dbg[36];
+ print 'dmidecode post process_data: ', Data::Dumper::Dumper $ram if $dbg[36];
eval $end if $b_log;
return $ram;
}
@@ -22821,7 +22945,7 @@ sub dboot_data {
eval $start if $b_log;
my $ram = [];
my $est = main::message('note-est');
- my ($arr,$derived_module_size,$subtract) = (0,0,0);
+ my ($arr,$derived_module_size,$slots_active,$subtract) = (0,0,0,0);
my ($holder);
foreach (@{$dboot{'ram'}}){
my ($addr,$detail,$device_detail,$ecc,$iic,$locator,$size,$speed,$type);
@@ -22839,6 +22963,7 @@ sub dboot_data {
# Then since we are on a new iic device, assume new ram array.
# This needs more data to confirm this guess.
$arr++;
+ $slots_active = 0;
}
if ($5){
$addr = hex($5);
@@ -22863,21 +22988,24 @@ sub dboot_data {
}
# We want to avoid netbsd trying to complete @ram without real data.
if (/:(\d+[MGT])B?\s(DDR[0-9]*)\b/){
- $size = main::translate_size($1)/1024;
+ $size = main::translate_size($1); # mbfix: /1024
$type = $2;
+ $slots_active++;
if ($addr){
$ram->[$arr]{'slots-16'} = $addr - 80 + 1 - $subtract;
$locator = 'Slot-' . $ram->[$arr]{'slots-16'};
}
+ $derived_module_size = $size if $size > $derived_module_size;
$ram->[$arr]{'device-count-found'}++;
# Build up actual capacity found for override tests
$ram->[$arr]{'max-capacity-16'} += $size;
$ram->[$arr]{'max-cap-qualifier'} = $est;
$ram->[$arr]{'slots-16'}++ if !$addr;
- $derived_module_size = $size if $size > $derived_module_size;
+ $ram->[$arr]{'slots-active'} = $slots_active;
$ram->[$arr]{'slots-qualifier'} = $est;
$ram->[$arr]{'eec'} = $ecc;
$ram->[$arr]{'derived-module-size'} = $derived_module_size;
+ $ram->[$arr]{'used-capacity'} += $size;
push(@{$ram->[$arr]{'modules'}},{
'device-type' => $type,
'device-type-detail' => $detail,
@@ -22895,11 +23023,11 @@ sub dboot_data {
$ram->[$i]{'slots'}++;
}
}
- print Data::Dumper::Dumper $ram if $dbg[36];
+ print 'dboot pre process_data: ', Data::Dumper::Dumper $ram if $dbg[36];
main::log_data('dump','@$ram',$ram) if $b_log;
process_data($ram) if @$ram;
main::log_data('dump','@$ram',$ram) if $b_log;
- print Data::Dumper::Dumper $ram if $dbg[36];
+ print 'dboot post process_data: ', Data::Dumper::Dumper $ram if $dbg[36];
eval $end if $b_log;
return $ram;
}
@@ -22922,6 +23050,7 @@ sub process_data {
# Make sure they are integers not string if empty.
$item->{'slots-5'} ||= 0;
$item->{'slots-16'} ||= 0;
+ $item->{'slots-active'} ||= 0;
$item->{'device-count-found'} ||= 0;
$item->{'max-capacity-5'} ||= 0;
$item->{'max-module-size'} ||= 0;
@@ -22929,14 +23058,16 @@ sub process_data {
# $item->{'max-module-size'} = 0;# debugger
# 1: If max cap 1 is null, and max cap 2 not null, use 2
if ($b_debug){
- print "1: mms: $item->{'max-module-size'} :dms: $item->{'derived-module-size'} :mc: $max_cap :uc: $item->{'used-capacity'}\n";
+ print "1: mms: $item->{'max-module-size'} :dms: $item->{'derived-module-size'} ";
+ print ":mc: $max_cap :uc: $item->{'used-capacity'}\n";
print "1a: s5: $item->{'slots-5'} s16: $item->{'slots-16'}\n";
}
if (!$max_cap && $item->{'max-capacity-5'}){
$max_cap = $item->{'max-capacity-5'};
}
if ($b_debug){
- print "2: mms: $item->{'max-module-size'} :dms: $item->{'derived-module-size'} :mc: $max_cap :uc: $item->{'used-capacity'}\n";
+ print "2: mms: $item->{'max-module-size'} :dms: $item->{'derived-module-size'} ";
+ print ":mc: $max_cap :uc: $item->{'used-capacity'}\n";
}
# 2: Now check to see if actually found module sizes are > than listed
# max module, replace if >
@@ -22946,7 +23077,8 @@ sub process_data {
$est_mod = $est;
}
if ($b_debug){
- print "3: dcf: $item->{'device-count-found'} :dms: $item->{'derived-module-size'} :mc: $max_cap :uc: $item->{'used-capacity'}\n";
+ print "3: dcf: $item->{'device-count-found'} :dms: $item->{'derived-module-size'} ";
+ print ":mc: $max_cap :uc: $item->{'used-capacity'}\n";
}
# Note: some cases memory capacity == max module size, so one stick will
# fill it but I think only with cases of 2 slots does this happen, so
@@ -23006,7 +23138,8 @@ sub process_data {
}
if ($b_debug){
- print "4: mms: $item->{'max-module-size'} :dms: $item->{'derived-module-size'} :mc: $max_cap :uc: $item->{'used-capacity'}\n";
+ print "4: mms: $item->{'max-module-size'} :dms: $item->{'derived-module-size'} ";
+ print ":mc: $max_cap :uc: $item->{'used-capacity'}\n";
}
# Some cases of type 5 have too big module max size, just dump the data
# then since we cannot know if it is valid or not, and a guess can be
@@ -23069,6 +23202,7 @@ sub process_data {
$est_slots = $item->{'slots-qualifier'};
$est_cap = $est;
}
+ $ram_total += $item->{'used-capacity'};
push(@result, {
'capacity' => $max_cap,
'cap-qualifier' => $est_cap,
@@ -23078,8 +23212,10 @@ sub process_data {
'mod-qualifier' => $est_mod,
'modules' => $item->{'modules'},
'slots' => $item->{'slots-16'},
+ 'slots-active' => $item->{'slots-active'},
'slots-qualifier' => $est_slots,
'use' => $item->{'use'},
+ 'used-capacity' => $item->{'used-capacity'},
'voltage-config' => $item->{'voltage-config'},
'voltage-max' => $item->{'voltage-max'},
'voltage-min' => $item->{'voltage-min'},
@@ -23105,30 +23241,26 @@ sub process_speed {
return [$speed,$speed_note];
}
-# This should be fixed, but for now, size in RAM is in MiB, not
-# KiB like the rest of inxi.
-# args: 0: size in MiB
+# args: 0: size in KiB
sub process_size {
my ($size) = @_;
my ($b_trim,$unit) = (0,'');
# print "size0: $size\n";
return 'N/A' if !$size;
- #return $size if $size =~ /\D/;
+ # we're going to preserve the bad data for output
return $size if !main::is_numeric($size);
# print "size: $size\n";
- # We only want a max 2 decimal places, and only when it's
- # a unit > 1 GiB.
- $b_trim = 1 if $size > 1024;
- # Switch it back to KiB for tool
- ($size,$unit) = main::get_size($size*1024);
+ # We only want max 2 decimal places, and only when it's a unit > 1 GiB.
+ $b_trim = 1 if $size > 1024**2;
+ ($size,$unit) = main::get_size($size);
$size = sprintf("%.2f",$size) if $b_trim;
$size =~ s/\.[0]+$//;
$size = "$size $unit";
return $size;
}
-# Note that even though MB should be 1000^x it's actually MiB etc. As with
-# process_size, this uses MiB not KiB.
+# arg: 0: size string; 1: working size. If calculated result > $size, uses new
+# value. If $data not valid, returns 0.
sub calculate_size {
my ($data, $size) = @_;
# Technically k is KiB, K is KB but can't trust that.
@@ -23136,8 +23268,6 @@ sub calculate_size {
my $working = $1;
# This converts it to KiB
my $working_size = main::translate_size($working);
- # But we want it back in MiB for RAM, that should get fixed
- $working_size = $working_size/1024 if $working_size;
# print "ws-a: $working_size s-1: $size\n";
if (main::is_numeric($working_size) && $working_size > $size){
$size = $working_size;
@@ -26217,7 +26347,7 @@ sub create_output {
my ($fs);
my ($j,$num) = (0,0);
@$unmounted = sort { $a->{'dev-base'} cmp $b->{'dev-base'} } @$unmounted;
- my $fs_skip = PartitionItem::fs_excludes('label-uuid');
+ my $fs_skip = PartitionItem::get_filters('fs-skip');
foreach my $row (@$unmounted){
$num = 1;
my $size = ($row->{'size'}) ? main::get_size($row->{'size'},'string') : 'N/A';
@@ -27374,21 +27504,22 @@ package CompilerVersion;
sub get {
eval $start if $b_log;
- my $compiler = [];
+ my $compiler;
if (my $file = $system_files{'proc-version'}){
- version_proc($compiler,$file);
+ version_proc(\$compiler,$file);
}
elsif ($bsd_type){
- version_bsd($compiler);
+ version_bsd(\$compiler);
}
+ $compiler ||= []; # we want an array ref to return if not set
eval $end if $b_log;
return $compiler;
}
+# args: 0: compiler by ref
sub version_bsd {
eval $start if $b_log;
my $compiler = $_[0];
- my (@working);
if ($alerts{'sysctl'}->{'action'} && $alerts{'sysctl'}->{'action'} eq 'use'){
if ($sysctl{'kernel'}){
my @working;
@@ -27399,7 +27530,7 @@ sub version_bsd {
if (/^kern.compiler_version/){
@working = split(/:\s*/, $_);
$working[1] =~ /.*(gcc|clang)\sversion\s([\S]+)\s.*/;
- @$compiler = ($1,$2);
+ $$compiler = [$1,$2];
last;
}
}
@@ -27417,13 +27548,12 @@ sub version_bsd {
eval $end if $b_log;
}
+# args: 0: compiler by ref; 1: proc file name
sub version_proc {
eval $start if $b_log;
my ($compiler,$file) = @_;
- my ($version);
- my @data = main::reader($file);
- my $result = $data[0] if @data;
- if ($result){
+ if (my $result = main::reader($file,'',0)){
+ my $version;
if ($fake{'compiler'}){
# $result = $result =~ /\*(gcc|clang)\*eval\*/;
# $result='Linux version 5.4.0-rc1 (sourav@archlinux-pc) (clang version 9.0.0 (tags/RELEASE_900/final)) #1 SMP PREEMPT Sun Oct 6 18:02:41 IST 2019';
@@ -27439,12 +27569,12 @@ sub version_proc {
if ($result =~ /(gcc|clang).*version\s([^,\s\)]+)/){
$version = $2;
$version ||= 'N/A';
- @$compiler = ($1,$version);
+ $$compiler = [$1,$version];
}
elsif ($result =~ /\((gcc|clang)[^\(]*\([^\)]+\)\s+([0-9\.]+)(\s[^.]*)?,\s*/){
$version = $2;
$version ||= 'N/A';
- @$compiler = ($1,$version);
+ $$compiler = [$1,$version];
}
}
main::log_data('dump','@$compiler',$compiler) if $b_log;
@@ -29589,10 +29719,11 @@ sub get_linux_distro {
$os_release_good_s .= 'pclinuxos-release|rpi-issue|SuSE-release';
# We need these empirically verified one by one as they appear, but always remember
# that stuff changes, legacy, deprecated, but these ideally are going to be right
- my $osr_good = 'manjaro|antergos|chakra|guix|mageia|pclinuxos|porteux|';
+ my $osr_good = 'antergos|chakra|guix|mageia|manjaro|oracle|pclinuxos|porteux|';
$osr_good .= 'raspberry pi os|slint|zorin';
# Force use of pretty name because that's only location of derived distro name
my $osr_pretty = 'zinc';
+
my ($b_issue,$b_lsb,$b_osr_pretty,$b_skip_issue,$b_skip_osr);
my ($issue,$lsb_release) = ('/etc/issue','/etc/lsb-release');
$b_issue = 1 if -f $issue;
@@ -29883,7 +30014,8 @@ sub system_base {
# osr base, distro id in issue
my $base_osr_issue = 'grml|linux lite|openmediavault';
# osr has distro name but has fedora centos redhat ID_LIKE and VERSION_ID same
- my $base_osr_redhat = 'almalinux|centos|rocky';
+ my $base_osr_redhat = 'almalinux|centos|eurolinux|oracle|puias|rocky|';
+ $base_osr_redhat .= 'scientific|springdale';
# osr has distro name but has ubuntu (or debian) ID_LIKE/UBUNTU_CODENAME
my $base_osr_ubuntu = 'feren|mint|neon|nitrux|pop!?_os|tuxedo|zinc|zorin';
my $base_upstream_lsb = '/etc/upstream-release/lsb-release';
@@ -30059,7 +30191,8 @@ sub get_os_release {
$working[1] =~ s/^(debian|ubuntu\sdebian|debian\subuntu)/ubuntu/;
$base_name = $working[1];
}
- if ($base_type eq 'rhel' && $working[1] =~ /$base_type/i){
+ # oracle ID_LIKE="fedora". Why? who knows.
+ if ($base_type eq 'rhel' && $working[1] =~ /rhel|fedora/i){
$base_name = 'RHEL';
$base_version = $version_id if $version_id;
}
@@ -30162,7 +30295,8 @@ sub debian_id {
'10' => 'buster',
'11' => 'bullseye',
'12' => 'bookworm',
- '13' => 'trixie',
+ '13' => 'trixie',
+ '14' => 'forky',
);
if (main::is_numeric($debian_version)){
$id .= " $debian_version " . $debians{int($debian_version)};
@@ -30191,8 +30325,9 @@ sub ubuntu_id {
my ($id) = ('');
# xx.04, xx.10
my %codenames = (
+ # '??' => '24.10',
# '??' => '24.04 LTS',
- # '??' => '23.10',
+ 'mantic' => '23.10',
'lunar' => '23.04',
'kinetic' => '22.10',
'jammy' => '22.04 LTS',
@@ -30360,9 +30495,10 @@ sub get_gcc_data {
if ($extra > 1){
# glob /usr/bin for gccs, strip out all non numeric values
@temp = globber('/usr/bin/gcc-*');
+ # usually like gcc-11 but sometimes gcc-11.2.0
foreach (@temp){
if (/\/gcc-([0-9.]+)$/){
- push(@$gccs, $1);
+ push(@$gccs, $1) if !$gcc || $1 ne $gcc;
}
}
}
@@ -31014,7 +31150,7 @@ sub get {
# netbsd 8.0 uses meminfo, but it uses it in a weird way
if (!$force{'vmstat'} && (!$bsd_type || ($force{'meminfo'} && $bsd_type)) &&
(my $file = $system_files{'proc-meminfo'})){
- $memory = meminfo_data($type,$file);
+ $memory = linux_data($type,$file);
}
else {
$memory = bsd_data($type);
@@ -31023,42 +31159,69 @@ sub get {
return $memory;
}
+# $memory:
+# 0: available (not reserved or iGPU)
+# 1: used (of available)
+# 2: used %
+# 3: gpu (raspberry pi only)
+# Linux only, but could be extended if anyone wants to do the work for BSDs
+# 4: array ref: sys_memory [total, blocks, block-size, count factor]
+# 5: array ref: proc/iomem [total, reserved, gpu]
+#
+# args: 0: source, the caller; 1: $row hash ref; 2: $num ref; 3: indent
sub row {
eval $start if $b_log;
- my ($source) = @_;
+ my ($source,$row,$num,$indent) = @_;
$loaded{'memory'} = 1;
- my $num = 0;
- my $row = {};
- my ($gpu_ram,$percent,$available,$used) = (0,'','N/A','N/A');
+ my ($available,$gpu_ram,$note,$total,$used);
my $memory = get('full');
if ($memory){
- $gpu_ram = $memory->[3] if $memory->[3];
- $available = main::get_size($memory->[0],'string') if $memory->[0];
- $used = main::get_size($memory->[1],'string') if $memory->[1];
- $used .= " ($memory->[2]%)" if $memory->[2];
+ # print Data::Dumper::Dumper $memory;
+ if ($memory->[3]){
+ $gpu_ram = $memory->[3];
+ }
+ elsif ($memory->[5] && $memory->[5][2]){
+ $gpu_ram = $memory->[5][2];
+ }
+ # Great, we have the real RAM data.
+ if ($show{'ram'} && ($total = RamItem::ram_total())){
+ $total = main::get_size($total,'string');
+ }
+ elsif ($memory->[4] || $memory->[5]){
+ process_total($memory,\$total,\$note);
+ }
if ($gpu_ram){
$gpu_ram = main::get_size($gpu_ram,'string');
}
+ $available = main::get_size($memory->[0],'string') if $memory->[0];
+ $used = main::get_size($memory->[1],'string') if $memory->[1];
+ $used .= " ($memory->[2]%)" if $memory->[2];
}
- $row->{main::key($num++,1,1,'System RAM')} = '';
- $row->{main::key($num++,0,2,'available')} = $available;
- $row->{main::key($num++,0,2,'used')} = $used;
- $row->{main::key($num++,0,2,'gpu')} = $gpu_ram if $gpu_ram;
+ my $field = ($source eq 'info') ? 'Memory' : 'System RAM';
+ $available ||= 'N/A';
+ $total ||= 'N/A';
+ $used ||= 'N/A';
+ $row->{main::key($$num++,1,$indent,$field)} = '';
+ $row->{main::key($$num++,1,$indent+1,'total')} = $total;
+ $row->{main::key($$num++,0,$indent+2,'note')} = $note if $note;
+ $row->{main::key($$num++,0,$indent+1,'available')} = $available;
+ $row->{main::key($$num++,0,$indent+1,'used')} = $used;
+ $row->{main::key($$num++,0,$indent+1,'igpu')} = $gpu_ram if $gpu_ram;
eval $end if $b_log;
- return $row;
}
-sub meminfo_data {
+## LINUX DATA ##
+sub linux_data {
eval $start if $b_log;
my ($type,$file) = @_;
- my ($available,$buffers,$cached,$free,$gpu,$not_used,$total) = (0,0,0,0,0,0,0);
- my $memory;
+ my ($available,$buffers,$cached,$free,$gpu,$not_used,$total_avail) = (0,0,0,0,0,0,0);
+ my ($iomem,$memory,$sys_memory,$total);
my @data = main::reader($file);
# Note: units kB should mean 1000x8 bits, but actually means KiB! Confusing
foreach (@data){
# Not actual total, it's total physical minus reserved/kernel/system.
if ($_ =~ /^MemTotal:/){
- $total = main::get_piece($_,2);
+ $total_avail = main::get_piece($_,2);
}
elsif ($_ =~ /^MemFree:/){
$free = main::get_piece($_,2);
@@ -31074,39 +31237,380 @@ sub meminfo_data {
}
}
$gpu = gpu_ram_arm() if $risc{'arm'};
+ if ($type ne 'short' && ($fake{'sys-mem'} || -d '/sys/devices/system/memory')){
+ sys_memory(\$sys_memory);
+ }
+ if ($type ne 'short' && ($fake{'iomem'} || ($b_root && -r '/proc/iomem'))){
+ proc_iomem(\$iomem);
+ }
# $gpu = main::translate_size('128M');
- # $total += $gpu; # not using because this ram is not available to system
+ # $total_avail += $gpu; # not using because this ram is not available to system
if ($available){
$not_used = $available;
}
# Seen fringe cases, where total - free+buff+cach < 0
# The idea is that the OS must be using 10MiB of ram or more
- elsif (($total - ($free + $buffers + $cached)) > 10000){
+ elsif (($total_avail - ($free + $buffers + $cached)) > 10000){
$not_used = ($free + $buffers + $cached);
}
# Netbsd goes < 0, but it's wrong, so dump the cache
- elsif (($total - ($free + $buffers)) > 10000){
+ elsif (($total_avail - ($free + $buffers)) > 10000){
$not_used = ($free + $buffers);
}
else {
$not_used = $free;
}
- my $used = ($total - $not_used);
- my $percent = ($used && $total) ? sprintf("%.1f", ($used/$total)*100) : '';
+ my $used = ($total_avail - $not_used);
+ my $percent = ($used && $total_avail) ? sprintf("%.1f", ($used/$total_avail)*100) : '';
if ($type eq 'short'){
- $percent = " ($percent%)" if $percent;
- $memory = [sprintf("%.1f/%.1f MiB", $used/1024, $total/1024) . $percent];
+ $memory = short_data($total_avail,$used,$percent);
}
else {
# raw return in KiB
- $memory = [$total,$used,$percent,$gpu];
+ $memory = [$total_avail,$used,$percent,$gpu,$sys_memory,$iomem];
}
- # print "$total, $used, $percent, $gpu\n";
+ # print "$total_avail, $used, $percent, $gpu\n";
+ # print Data::Dumper::Dumper $memory;
main::log_data('data',"memory ref: $memory") if $b_log;
eval $end if $b_log;
return $memory;
}
+# All values 0 if not root, but it is readable.
+# See inxi-perl/dev/code-snippets.pl for original attempt, with pci/reserved
+# args: 0: $iomem by ref
+sub proc_iomem {
+ eval $start if $b_log;
+ my $file = '/proc/iomem';
+ my ($buffer,$gpu,$pci,$reserved,$rom,$system) = (0,0,0,0,0,0);
+ my $b_reserved;
+ no warnings 'portable';
+ if ($fake{'iomem'}){
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-128gb-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-544mb-igpu.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-64mb-vram-stolen.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-rh-1-matrox.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-2-vram.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-512mb-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-518mb-reserved-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-512mb-2-onboardgpu-active.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-512mb-system-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-257.18gb-system-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-192gb-system-1.txt";
+ $file = "$ENV{'HOME'}/bin/scripts/inxi/data/memory/proc-iomem-1012mb-igpu.txt";
+ }
+ foreach ((main::reader($file),'EOF')){
+ if ($dbg[54]){
+ if (/^\s*([0-9a-f]+)-([^\s]+) : /){
+ print $_,"\n",' size: ';
+ print main::get_size(((hex($2) - hex($1) + 1)/1024),'string'), "\n";
+ }
+ }
+ # Get everythign solidly System RAM
+ if (/^([0-9a-f]+)-([^\s]+) : (System RAM)$/i){
+ $system += hex($2) - hex($1) + 1;
+ }
+ elsif (/^([0-9a-f]+)-([^\s]+) : (Ram buffer)$/i){
+ $buffer += hex($2) - hex($1) + 1;
+ }
+ # Sometimes primary Reserved block contains PCI and other non RAM devices,
+ # but also can contain non RAM addresses, maybe NVMe?
+ elsif (/^([0-9a-f]+)-([^\s]+) : (Reserved)$/i){
+ $reserved += hex($2) - hex($1) + 1;
+ }
+ # Legacy System ROM not in a Reserved block, primary item.
+ elsif (/^\s*([0-9a-f]+)-([^\s]+) : (System ROM)$/i){
+ $rom += hex($2) - hex($1) + 1;
+ }
+ elsif (/^([0-9a-f]+)-([^\s]+) : (ACPI Tables)$/i){
+ $rom += hex($2) - hex($1) + 1;
+ }
+ # Incomplete because sometimes Reserved blocks contain PCI etc devices
+ elsif (/^([0-9a-f]+)-([^\s]+) : (PCI .*)$/){
+ $pci += hex($2) - hex($1) + 1;
+ }
+ # Graphics stolen memory/Video RAM area, but legacy had inside PCI blocks,
+ # not reserved, or as primary. That behavior seems to have changed.
+ if (/^\s*([0-9a-f]+)-([^\s]+) : (?:(Video RAM|Graphics).*)$/i){
+ $gpu += hex($2) - hex($1) + 1;
+ }
+ }
+ if ($dbg[54] || $b_log){
+ my $d = ['iomem:','System: ' . main::get_size(($system/1024),'string'),
+ 'Reserved: ' . main::get_size(($reserved/1024),'string'),
+ 'Buffer: ' . main::get_size(($buffer/1024),'string'),
+ 'iGPU: ' . main::get_size(($gpu/1024),'string'),
+ 'ROM: ' . main::get_size(($rom/1024),'string'),
+ 'System+iGPU+buffer+rom: ' . main::get_size((($system+$gpu+$buffer+$rom)/1024),'string'),
+ ' Raw GiB: ' . ($system+$gpu+$buffer+$rom)/1024**3,
+ 'System+reserved: ' . main::get_size((($system+$reserved)/1024),'string'),
+ ' Raw GiB: ' . ($system+$reserved)/1024**3,
+ 'System+reserved+buffer: ' . main::get_size((($system+$reserved+$buffer)/1024),'string'),
+ ' Raw GiB: ' . ($system+$reserved+$buffer)/1024**3,
+ 'Reserved-iGPU: ' . main::get_size((($reserved-$gpu)/1024),'string'),
+ 'PCI Bus: ' . main::get_size(($pci/1024),'string')];
+ main::log_data('dump','$d iomem',$d) if $b_log;
+ print "\n",join("\n",@$d),"\n\n" if $dbg[54];
+ }
+ if ($gpu || $system || $reserved){
+ # This combination seems to provide the bwest overall result
+ $system += $gpu + $rom + $buffer;
+ ${$_[0]} = [$system/1024,$reserved/1024,$gpu/1024];
+ }
+ main::log_data('dump','$iomem',$_[0]) if $b_log;
+ print 'proc/iomem: ', Data::Dumper::Dumper $_[0] if $dbg[53];
+ eval $end if $b_log;
+}
+
+# Note: seen case where actual 128 GiB, result here 130, 65x2GiB. Also cases
+# where blocks under expected total, this may be related to active onboard gpu.
+sub sys_memory {
+ eval $start if $b_log;
+ return if !$fake{'sys-mem'} && ! -r '/sys/devices/system/memory/block_size_bytes';
+ my ($count,$factor,$size,$total) = (0,1,0,0);
+ # state = off,online; online = 1/0
+ foreach my $online (main::globber('/sys/devices/system/memory/memory*/online')){
+ $count++ if main::reader($online,'',0); # content 1/0, so will read as t/f
+ }
+ if ($count){
+ $size = main::reader('/sys/devices/system/memory/block_size_bytes','',0);
+ if ($size){
+ $size = hex($size)/1024; # back to integer KiB
+ $total = $count * $size;
+ }
+ }
+ if ($fake{'sys-mem'}){
+ # ($total,$count,$size) = (,,); #
+ # ($total,$count,$size) = (4194304,32,131072); # 4gb
+ # ($total,$count,$size) = (7864320,60,131072); # 7.5 gb, -4 blocks
+ # ($total,$count,$size) = (136314880,65,2097152); # 130 gb, +1 block
+ # ($total,$count,$size) = (8126464,62,131072); # 7.75 gb, -2 blocks, vram?
+ # ($total,$count,$size) = (33554432,256,131072); # 32 gb
+ # ($total,$count,$size) = (8388608,64,131072); # 8gb
+ # ($total,$count,$size) = (270532608,129,2097152); # 258 gb, +1 block
+ # ($total,$count,$size) = (17563648,134,131072); # 16.75 gb, +6 block
+ # ($total,$count,$size) = (3801088,29,131072); # 3.62 gb, -3 blocks
+ # ($total,$count,$size) = (67108864,32,2097152); # 64 gb
+ # ($total,$count,$size) = (524288,4,131072); # 512 mb, maybe -4 blocks, vm
+ }
+ # Max stick size assumed: 64 blocks: 8 GiB/128 GiB min module: 2 GiB/32 GiB
+ # 128 blocks: 16 GiB/256 GiB min module: 4 GiB/64 GiB but no way to know
+ # Note: 128 MiB blocks; > 32 GiB, 2 GiB blocks, I think.
+ # 64: 8 GiB/256 GiB, min module: 2 GiB/32 GiB
+ if ($count > 32){
+ $factor = 16;}
+ # 32: 4 GiB/64 GiB, min module: 1 GiB/16 GiB
+ elsif ($count > 16){
+ $factor = 8;}
+ # 16: 2 GiB, min module: 512 MiB
+ elsif ($count > 8){
+ $factor = 4;}
+ # 8: 1 GiB, min module: 256 MiB
+ elsif ($count > 4){
+ $factor = 2;}
+ # 4: 512 MiB, min module: 128 MiB
+ else {
+ $factor = 1;}
+ if ($total || $count || $size){
+ ${$_[0]} = [$total,$count,$size,$factor];
+ }
+ if ($dbg[54] || $b_log){
+ my $d = ['/sys:','Total: ' . main::get_size($total,'string'),
+ 'Blocks: ' . $count,
+ 'Block-size: ' . main::get_size($size,'string'),
+ "Count-factor: $count % $factor: " . $count % $factor];
+ main::log_data('dump','$d sys-mem',$d) if $b_log;
+ print "\n",join("\n",@$d),"\n\n" if $dbg[54];
+ }
+ main::log_data('dump','$sys_memory',$_[0]) if $b_log;
+ print 'sys memory: ', Data::Dumper::Dumper $_[0] if $dbg[53];
+ eval $end if $b_log;
+}
+
+# These are hacks since the phy ram real data is not available in clear form
+# args: 0: memory array ref; 1: $total ref; 2: $note ref.
+sub process_total {
+ eval $start if $b_log;
+ my ($memory,$total,$note) = @_;
+ my ($d,$b_vm,@info);
+ my $src = '';
+ $b_vm = MachineItem::is_vm() if $show{'machine'};
+ # Seen case where actual 128 GiB, result here 130, 65x2GiB. Maybe nvme?
+ # This can be over or under phys ram
+ if ($memory->[4] && $memory->[4][0]){
+ @info = main::get_size($memory->[4][0]);
+ # We want to show note for probably wrong results
+ if ((!$fake{'sys-mem'} && $memory->[0] && $memory->[4][0] < $memory->[0]) ||
+ (!$b_vm && $memory->[4][1] % $memory->[4][3] != 0)){
+ $$note = main::message('note-check');
+ }
+ $src = 'sys';
+ }
+ # Note: this is a touch under the real ram amount, varies, igpu/vram can eat it.
+ # This working total will only be under phys ram.
+ if ($memory->[5] && $memory->[5][0] &&
+ (!$memory->[4] || !$memory->[4][0] || ($memory->[4][0] != $memory->[5][0]))){
+ @info = main::get_size($memory->[5][0]);
+ $src = 'iomem';
+ }
+ if (@info){
+ $$note = '';
+ if (!$b_vm){
+ # $info[0] = 384;
+ # $info[1] = 'MiB';
+ my ($factor,$factor2) = (1,0.5);
+ # For M, assume smallest is 128, anything older won't even work probably.
+ # For T RAM, the system ram is going to be 99.9% of physical because the
+ # reserved stuff is going to be tiny, I believe. We will see.
+ # T array stick sizes: 128/256/512/1024 G
+ # Note: samsung ships 1T modules (2024?), 512G (2023).
+ if ($info[0] > 512){
+ $factor = ($info[1] eq 'MiB') ? 256 : 64;
+ }
+ elsif ($info[0] > 256){
+ $factor = ($info[1] eq 'MiB') ? 128 : 32;
+ }
+ elsif ($info[0] > 128){
+ $factor = ($info[1] eq 'MiB') ? 64 : 16;
+ }
+ elsif ($info[0] > 64){
+ $factor = 8;
+ }
+ elsif ($info[0] > 16){
+ $factor = 4;
+ }
+ elsif ($info[0] > 8){
+ $factor = 4;
+ }
+ elsif ($info[0] > 4){
+ $factor = 2;
+ }
+ elsif ($info[0] > 3){
+ $factor = 1;
+ }
+ elsif ($info[0] > 2){
+ $factor = ($info[1] eq 'TiB') ? 0.25 : 0.5;
+ }
+ # Note: get_size returns 1 as 1024, so we never actually see 1
+ elsif ($info[0] > 1){
+ $factor = ($info[1] eq 'TiB') ? 0.125 : 0.25;
+ }
+ my $result = $info[0] / $factor;
+ my $mod = ((100 * $result) % 100);
+ if ($b_log || $dbg[54]){
+ push(@$d,"src: $src result: $info[0] / $factor: $result math-modulus: $mod");
+ }
+ if ($mod > 0){
+ my ($check,$working) = (0,0);
+ # Sometimes Perl generates a tiny value over 0.1: 0.100000000000023
+ # but also we want to be a little loose here. Note that when high
+ # numbers, like 1012 M, we want the math much looser.
+ # Within ~ 5%
+ if ($info[1] eq 'MiB'){
+ if ($info[0] > 768){
+ $check = 64;
+ }
+ elsif ($info[0] > 512){
+ $check = 32;
+ }
+ elsif ($info[0] > 256){
+ $check = 16;
+ }
+ else {
+ $check = 4;
+ }
+ }
+ # Within ~ 1%
+ elsif ($info[1] eq 'GiB'){
+ if ($info[0] > 512){
+ $check = 4;
+ }
+ elsif ($info[0] > 256){
+ $check = 2;
+ }
+ elsif ($info[0] > 3){
+ $check = 0.25;
+ }
+ else {
+ $check = 0.1;
+ }
+ }
+ # Will need to verify this T assumption on real data one day, but keep
+ # in mind how much reserved ram this would be!
+ elsif ($info[1] eq 'TiB'){
+ if ($info[0] > 16){
+ $check = 0.25;
+ }
+ elsif ($info[0] > 8){
+ $check = 0.15;
+ }
+ elsif ($info[0] > 2){
+ $check = 0.1;
+ }
+ else {
+ $check = 0.05;
+ }
+ }
+ # iomem is always under, sys can be over or under. we want fractional
+ # corresponding value over or under result.
+ # sys has block sizes: 128M, 2G, 32G, so sizes will always be divisible
+ if ($src eq 'sys'){
+ if ($info[0] > 64){
+ $factor2 = 0.25;
+ }
+ }
+ if ($src eq 'sys' && int($result + $factor2) == int($result)){
+ $working = int($result) * $factor;
+ }
+ else {
+ $working = POSIX::ceil($result) * $factor;
+ }
+ if ($b_log || $dbg[54]){
+ push(@$d, "factor2: $factor2 floor_res+fact2: " . int($result + $factor2),
+ "ceil_result * factor: " . (POSIX::ceil($result) * $factor),
+ "floor_result * factor: " . (int($result) * $factor));
+ }
+ if (abs(($working - $info[0])) < $check){
+ if ($src eq 'sys' && $info[0] != $working){
+ $$note = main::message('note-est');
+ }
+ if ($b_log || $dbg[54]){
+ push(@$d,"check less: ($working - $info[0]) < $check: ",
+ "result: inside ceil < $check, clean");
+ }
+ }
+ else {
+ if ($b_log || $dbg[54]){
+ push(@$d,"check not less: ($working - $info[0]) < $check: ",
+ "set: $info[0] = $working");
+ }
+ $$note = main::message('note-est');
+ }
+ $info[0] = $working;
+ }
+ else {
+ if ($b_log || $dbg[54]){
+ push(@$d,"result: clean match, no change: $info[0] $info[1]");
+ }
+ }
+ }
+ else {
+ my $dec = ($info[1] eq 'MiB') ? 1: 2;
+ $info[0] = sprintf("%0.${dec}f",$info[0]) + 0;
+ if ($b_log || $dbg[54]){
+ push(@$d,"result: vm, using size: $info[0] $info[1]");
+ }
+ }
+ $$total = $info[0] . ' ' . $info[1];
+ }
+ if ($b_log || $dbg[54]){
+ main::log_data('dump','debugger',$d) if $b_log;
+ print Data::Dumper::Dumper $d if $dbg[54];
+ }
+ eval $end if $b_log;
+}
+
+## BSD DATA ##
## openbsd/linux
# procs memory page disks traps cpu
# r b w avm fre flt re pi po fr sr wd0 wd1 int sys cs us sy id
@@ -31131,7 +31635,7 @@ sub bsd_data {
my (@data,$memory,$message);
# my $arg = ($bsd_type ne 'openbsd' && $bsd_type ne 'dragonfly') ? '-H' : '';
if (my $program = main::check_program('vmstat')){
- # see above, it's the last line. -H makes it hopefully all in kB so no need
+ # See above, it's the last line. -H makes it hopefully all in kB so no need
# for K/M/G tests, note that -H not consistently supported, so don't use.
my @vmstat = main::grabber("vmstat 2>/dev/null",'\n','strip');
main::log_data('dump','@vmstat',\@vmstat) if $b_log;
@@ -31145,14 +31649,14 @@ sub bsd_data {
my $row = $vmstat[-1];
if ($row){
@data = split(/\s+/, $row);
- # openbsd 6.3, dragonfly 5.x introduced an M / G character, sigh.
+ # Openbsd 6.3, dragonfly 5.x introduced an M / G character, sigh.
if ($avm > 0 && $data[$avm] && $data[$avm] =~ /^([0-9\.]+[KGMT])(iB|B)?$/){
$data[$avm] = main::translate_size($1);
}
if ($fre > 0 && $data[$fre] && $data[$fre] =~ /^([0-9\.]+[KGMT])(iB|B)?$/){
$data[$fre] = main::translate_size($1);
}
- # dragonfly can have 0 avg, or no avm, sigh, but they may fix that so make test dynamic
+ # Dragonfly can have 0 avg, or no avm, sigh, but they may fix that so make test dynamic
if ($avm > 0 && $data[$avm] != 0){
$av_pages = ($bsd_type !~ /^(net|open)bsd$/) ? sprintf('%.1f',$data[$avm]/1024) : $data[$avm];
}
@@ -31161,13 +31665,13 @@ sub bsd_data {
}
}
}
- ## code to get total goes here:
+ # Code to get total goes here:
if ($alerts{'sysctl'}->{'action'} eq 'use'){
- # for dragonfly, we will use free mem, not used because free is 0
+ # For dragonfly, we will use free mem, not used because free is 0
my @working;
if ($sysctl{'memory'}){
foreach (@{$sysctl{'memory'}}){
- # freebsd seems to use bytes here
+ # Freebsd seems to use bytes here
if (!$real_mem && /^hw.physmem:/){
@working = split(/:\s*/, $_);
# if ($working[1]){
@@ -31177,7 +31681,7 @@ sub bsd_data {
last if $free_mem;
}
# But, it uses K here. Openbsd/Dragonfly do not seem to have this item
- # this can be either: Free Memory OR Free Memory Pages
+ # This can be either: Free Memory OR Free Memory Pages
elsif (/^Free Memory:/){
@working = split(/:\s*/, $_);
$working[1] =~ s/[^0-9]+//g;
@@ -31190,27 +31694,25 @@ sub bsd_data {
else {
$message = "sysctl $alerts{'sysctl'}->{'action'}"
}
- # not using, but leave in place for a bit in case we want it
+ # Not using, but leave in place for a bit in case we want it
# my $type = ($free_mem) ? ' free':'' ;
- # hack: temp fix for openbsd/darwin: in case no free mem was detected but we have physmem
+ # Hack: temp fix for openbsd/darwin: in case no free mem was detected but we have physmem
if (($av_pages || $free_mem) && !$real_mem){
my $error = ($message) ? $message: 'total N/A';
my $used = (!$free_mem) ? $av_pages : $real_mem - $free_mem;
if ($type eq 'short'){
- $used = sprintf("%.1f",$used/1024);
- $memory = ["$used/($error) MiB"];
+ $memory = short_data($error,$used);
}
else {
$memory = [$error,$used,undef];
}
}
- # use openbsd/dragonfly avail mem data if available
+ # Use openbsd/dragonfly avail mem data if available
elsif (($av_pages || $free_mem) && $real_mem){
my $used = (!$free_mem) ? $av_pages : $real_mem - $free_mem;
my $percent = ($used && $real_mem) ? sprintf("%.1f", ($used/$real_mem)*100) : '';
if ($type eq 'short'){
- $percent = " ($percent)" if $percent;
- $memory = [sprintf("%.1f/%.1f MiB", $used/1024, $real_mem/1024) . $percent];
+ $memory = short_data($real_mem,$used,$percent);
}
else {
$memory = [$real_mem,$used,$percent,0];
@@ -31220,7 +31722,29 @@ sub bsd_data {
return $memory;
}
-# raspberry pi only
+## TOOLS ##
+# args: 0: avail memory; 1: used memory; 2: percent used
+sub short_data {
+ # some BSDs, no available
+ my @avail = (main::is_numeric($_[0])) ? main::get_size($_[0]) : ($_[0]);
+ my @used = main::get_size($_[1]);
+ my $string = '';
+ if ($avail[1] && $used[1]){
+ if ( $avail[1] eq $used[1]){
+ $string = "$used[0]/$avail[0] $used[1]";
+ }
+ else {
+ $string = "$used[0] $used[1]/$avail[0] $avail[1]";
+ }
+ }
+ elsif ($used[1]){
+ $string = "$used[0]/[$avail[0]] $used[1]";
+ }
+ $string .= " ($_[2]%)" if $_[2];
+ return $string;
+}
+
+# Raspberry pi only
sub gpu_ram_arm {
eval $start if $b_log;
my ($gpu_ram) = (0);
@@ -31235,13 +31759,6 @@ sub gpu_ram_arm {
eval $end if $b_log;
return $gpu_ram;
}
-# standard systems, not used currently, but maybe one day?
-sub get_gpu_ram {
- eval $start if $b_log;
- my ($gpu_ram) = (0);
- eval $end if $b_log;
- return $gpu_ram;
-}
}
sub get_module_version {
@@ -34548,7 +35065,7 @@ sub short_output {
}
}
my $memory = MemoryData::get('short');
- @$memory = ('N/A') if !$memory || !@$memory || !$memory->[0];
+ $memory = 'N/A' if !$memory;
# print join('; ', @cpu), " sleep: $cpu_sleep\n";
if (!$loaded{'shell-data'} && $ppid && (!$b_irc || !$client{'name-print'})){
ShellData::set();
@@ -34563,7 +35080,7 @@ sub short_output {
main::key($num++,0,0,$speed_key) => $speed,
main::key($num++,0,0,$kernel_os) => join(' ', @{main::get_kernel_data()}),
main::key($num++,0,0,'Up') => main::get_uptime(),
- main::key($num++,0,0,'Mem') => $memory->[0],
+ main::key($num++,0,0,'Mem') => $memory,
main::key($num++,0,0,'Storage') => $disk_string,
# could make -1 for ps aux itself, -2 for ps aux and self
main::key($num++,0,0,'Procs') => scalar @ps_aux,
@@ -34583,7 +35100,7 @@ sub info_item {
my $running_in = '';
my $data_name = main::key($prefix++,1,0,'Info');
my ($b_gcc,$gcc,$index);
- my ($gpu_ram,$parent,$percent,$total,$used) = (0,'','','','');
+ my ($available,$gpu_ram,$parent,$percent,$used) = ('',0,'','','');
my $gccs = main::get_gcc_data();
if (@$gccs){
$gcc = shift @$gccs;
@@ -34605,19 +35122,8 @@ sub info_item {
$data->{$data_name}[$index]{main::key($num++,0,2,'wakeups')} = $wakeups if defined $wakeups;
}
if (!$loaded{'memory'}){
- my $memory = MemoryData::get('full');
- if ($memory && @$memory){
- $gpu_ram = $memory->[3] if $memory->[3];
- $total = ($memory->[0]) ? main::get_size($memory->[0],'string') : 'N/A';
- $used = ($memory->[1]) ? main::get_size($memory->[1],'string') : 'N/A';
- $used .= " ($memory->[2]%)" if $memory->[2];
- if ($gpu_ram){
- $gpu_ram = main::get_size($gpu_ram,'string');
- }
- }
- $data->{$data_name}[$index]{main::key($num++,1,1,'Memory')} = '';
- $data->{$data_name}[$index]{main::key($num++,0,2,'available')} = $total;
- $data->{$data_name}[$index]{main::key($num++,0,2,'used')} = $used;
+ my $row = {};
+ main::MemoryData::row('info',$data->{$data_name}[$index],\$num,1);
}
if ($gpu_ram){
$data->{$data_name}[$index]{main::key($num++,0,2,'gpu')} = $gpu_ram;
diff --git a/inxi.1 b/inxi.1
index a5edc13..852d759 100644
--- a/inxi.1
+++ b/inxi.1
@@ -15,7 +15,7 @@
.\" with this program; if not, write to the Free Software Foundation, Inc.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
-.TH INXI 1 "2023\-05\-07" "inxi" "inxi manual"
+.TH INXI 1 "2023\-07\-10" "inxi" "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
@@ -390,11 +390,7 @@ for extra information (init type/version, runlevel/target, packages).
Note: if \fB\-m\fR or \fB\-tm\fR are active, the memory item will show in the
main Memory: report of \fB\-m\fR/\fB\-tm\fR/, not in \fB\Info:\fR.
-See \fB\-m\fR for explanation of \fBMemory: available:\fR.
-
-Raspberry Pi only: uses \fBvcgencmd get_mem gpu\fR to get gpu RAM amount, if
-user is in video group and \fBvcgencmd\fR is installed. Uses this result to
-increase the \fBMemory:\fR amount and \fBused:\fR amounts.
+See \fB\-m\fR for explanation of \fBMemory:\fR fields and values..
.TP
.B \-j\fR, \fB\-\-swap\fR
@@ -548,7 +544,8 @@ If the detected speed is logically absurd, like 1 MT/s or 69910 MT/s, adds:
.nf
\fBMemory:
- System RAM: available: 31.38 GiB used: 20.65 GiB (65.8%)
+ System RAM: total: 32 GiB note: est. available: 31.38 GiB
+ used: 20.65 GiB (65.8%)
Array\-1: capacity: N/A slots: 4 note: check EC: N/A
Device\-1: DIMM_A1 type: DDR3 size: 8 GiB speed: 1600 MT/s (800 MHz)
Device\-2: DIMM_A2 type: DDR3 size: 8 GiB speed: spec: 1600 MT/s (800 MHz)
@@ -561,10 +558,49 @@ If the detected speed is logically absurd, like 1 MT/s or 69910 MT/s, adds:
See \fB\-\-memory\-modules\fR and \fB\-\-memory\-short\fR if you want a
shorter report.
-Note: the \fBSystem Ram: available:\fR is actually the total installed RAM minus
-some reserved and kernel code RAM (and in some cases GPU assigned main system
-RAM) that is allocated on system boot, and thus is generally less than the
-actual physical RAM installed.
+Notes on \fBSystem RAM:\fR / \fBMemory:\fR report item:
+
+* \fBtotal:\fR and \fBigpu:\fR do not show for short form.
+
+* The \fBtotal:\fR can come from several possible sources:
+
+\- If not superuser, and if \fI/sys/devices/system/memory\fR exists, it will
+estimate the total RAM based on how many RAM blocks and their size. Sometimes
+the block count is not an exact match to installed RAM, and inxi will attempt to
+guess the actual RAM amount, except for virtual machines. When it synthesizes
+the actual physical RAM total, it will show \fBnote: est.\fR.
+
+Note that not all kernels are compiled to support generating this /sys
+directory (kernel needs to be compiled with \fBCONFIG_MEMORY_HOTPLUG\fR).
+
+\- For OpenBSD and not superuser, the total comes from the detected RAM in
+dboot, if available.
+
+\- If superuser, and if \fB\-m\fR used, it comes from the dmidecode RAM totals
+if available, and if not, it comes from counting up the System RAM ranges in
+\fI/proc/iomem\fR (Linux only), then rounding up, since that total is usually
+slightly under the actual physical RAM total. If inxi is unsure about the total,
+it will show \fBnote: est.\fB.
+
+If no total data found, shows \fBtotal: N/A\fB.
+
+* The \fBavailable:\fR item is the total installed RAM minus some reserved and
+kernel code RAM (and in some cases iGPU assigned main system RAM) that is
+allocated on system boot, and thus is generally less than the actual physical
+RAM installed. This is called MemTotal in free/meminfo even though it isn't,
+though it is the total available the kernel has to work with.
+
+* The \fBused:\fR is the percent of the available RAM used, NOT of the total
+physical RAM.
+
+* The \fBigpu:\fR item either comes from Raspberry Pi gpu RAM, or from
+\fI/proc/iomem\fR. The latter source is Linux + superuser only, and is not
+guaranteed to be accurate, but sometimes is. That is for iGPU system RAM used,
+not for standalone GPUs with their own internal RAM. Not all types of internal
+VRAM are detectable, it depends on how the hardware assigns RAM to iGPU.
+
+Raspberry Pi uses \fBvcgencmd get_mem gpu\fR to get gpu RAM amount, if
+user is in video group and \fBvcgencmd\fR is installed.
.TP
.B \-\-memory\-modules\fR, \fB\-\-mm\fR
@@ -784,7 +820,7 @@ Make sure that there is no space between letters and numbers (e.g. write as
If the \fB\-I\fR or \fB\-m\fR lines are not triggered, will also show the
system RAM used/total information.
-See \fB\-m\fR for explanation of \fBRAM: total\-available:\fR.
+See \fB\-m\fR for explanation of \fBSystem RAM:\fR fields and values.
.TP
.B \-t cm\fR
@@ -1486,6 +1522,8 @@ the sound API/server.
.TP
.B \-xx \-B\fR
+\- Adds current power use, in watts.
+
\- Adds serial number.
.TP
diff --git a/inxi.changelog b/inxi.changelog
index 321ecaf..d885a86 100644
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,231 @@
================================================================================
+Version: 3.3.28
+Patch: 00
+Date: 2023-07-10
+--------------------------------------------------------------------------------
+RELEASE NOTES:
+--------------------------------------------------------------------------------
+
+New version, new man. Continuing the Memory info rollout started in 3.3.27.
+
+--------------------------------------------------------------------------------
+SPECIAL THANKS:
+
+1. Thanks to linuxquestions.org Slackware forums for poking around a bit at the
+new Memory total logic.
+
+--------------------------------------------------------------------------------
+KNOWN ISSUES:
+
+1a. MEMORY: The memory total: has to be synthesized in some cases, based on some
+math and educated guessing. When these guesses fall outside of predetermined
+ranges, inxi will show note: est. to let the user know the total was synthesized
+and possibly incorrect. For detected virtual machines, inxi does not try to
+synthesize the total because a VM can have any amount of RAM assigned.
+
+If superuser, and -m used, shows the real total from dmidecode if any RAM was
+found. Not all systems have DMI RAM data however, or have dmidecode installed.
+Will fallback to sythetic method in that case, which is usually right.
+
+1b. MEMORY: With the superuser /proc/iomem method, if on a VM and not using even
+GiB sized RAM ollocation, and -M is not triggered (which usually lets inxi know
+it's a VM), the total will get rounded up or down based on a set of rules. For
+example, 2.5 GiB real would become 3 GiB. I don't see any solution to this,
+either assume the /proc/iomem is right but needs rounding up, or assume the /sys
+block counts are right, or remove the feature.
+
+Shows note: est. in cases where the rounded total is greater than a dynamic
+factor difference from the internal total amount.
+
+2. GENERAL/GRAPHICS: The problem of users showing up, requesting a feature, then
+not doing any work, research, supplying energy, interest, and dare I say,
+passion - nothing, expecting 'someone else' to do the work for them, continues,
+sadly, with the recent request for vulkan data for Graphics. This appears to be
+a problem more with the modern generation of free software users, I don't
+remember this type of attitude 20 years ago, but I did watch it as it started
+getting more common. Demotivating to be honest, but maybe one day someone will
+show up who actually cares enough to help get the features they want developed.
+
+While I am leaving that up as a low priority feature request, I am not
+personally interested in that feature, nor is anyone else I asked, and given how
+much raw data there is, and how difficult it is to parse, I'll just leave it as
+an existing issue which might get work in a few years time, or not, basically
+will require someone showing up who actually actively cares.
+
+--------------------------------------------------------------------------------
+BUGS:
+
+1. DISK: total: used: report could have had wrong results for used:, like used
+being > total: because the filter lists were missing some file systems for
+exclusion. More of a fix than a bug, but users might see it as a bug.
+
+--------------------------------------------------------------------------------
+FIXES:
+
+1. INFO: get_gcc_data(): was showing same GCC version as main and alternate.
+Failed to filter out the discovered primary, that is. This is because usually
+name is gcc-11 but sometimes it's the whole version, like gcc-11.2.0, the full
+version string. This is the case in Slackware for example.
+
+2. SHORT: MEMORY: BSD: did not show '%' for memory used percent, just the
+number.
+
+3. DRIVES/PARTITIONS: PartitionItem::set_filters() added many more exclude
+types, that will help avoid both creating wrong disk used totals, and also not
+show label:/uuid: fields for filesystem types that don't have uuid/labels. There
+were a lot missing: encrypted, distributed, stackable, remote. Should clean up
+wrong disk used values in some cases.
+
+4a. PARTITIONS: PartitionItem::set_filters(). Added a lot of file systems, many
+fuse, distributed, stackable types.
+
+4b. PARTITIONS: Extended remote file system ID by fs, and added fuse fs for
+local mounts, like gvfs, mtp, ptp and many other variants, that's things like
+mounting apple partition, android, iphone, archives, etc. This should correct an
+entire class of source: ERR-102 outputs.
+
+--------------------------------------------------------------------------------
+ENHANCEMENTS:
+
+1. BATTERY: Added 'power' to battery report. That's the amount of watts its
+using at that moment, so not super useful since it's running inxi at that
+moment. But the data was there, so might as well show it. Only for -Bxx since it
+will be so variable. Shows after the charge/condition item.
+
+2. SYSTEM: DistroData: added Oracle id and system base. Added Springdale/PUIAS
+system base support. Note, unusually, Eurolinux, ScientificLinux 'just worked'
+re id and system base even though that had never been explicitly added. This is
+because their os-release file contains 'centos' string.
+
+3. SYSTEM: DistroData: Added ubuntu mantic minotaur to ubuntu id matching table.
+This only really is used by Mint, but there you have it. Also added Debian 14
+codename Forky.
+
+4a. MEMORY: Add total RAM from one of following:
+
+* /sys/devices/system/memory (if it's available). This directory has to be
+compiled into kernel, so is not always present. This source has advantage of
+being user readable. If out of set bounds, shows note: est. to let user know
+it's an estimate.
+
+* If superuser and /proc/iomme, gets the total from /proc/iomem using some
+tricks and synthetic methods, which in general is pretty accurate, but when out
+of the bounds set, shows note: est. to let user know results are only estimates.
+This overrides /sys total.
+
+* If -m and dmidecode data found, uses the real RAM module total. For Linux and
+superuser. This overrides iomem and /sys totals.
+
+4b. MEMORY: add iGPU RAM from /proc/iomem when detected. Requires sudo/root.
+
+4c. MEMORY: using the real -m/RAM total for memory total when available, since
+that is the actual value we want, not the estimated stuff from /proc/iomem or
+/sys/devices/system.
+
+5. RAM: added a long time oversight, lack of per array RAM installed size and
+occupied slots (modules). Those are now part of the Array line for each set of
+modules. Since total already shows in System RAM line above, the granular per
+array installed size total only shows if > 1 array is present, ie, almost never.
+
+6. DRIVES: disk vendors, added more matches and vendors. We'll know the world is
+changing in a significant way when no new vendors appear for a while, but that's
+unlikely in the near term.
+
+7. CPU: cpu_arch(), a few new ids added.
+
+8. GRAPHICS: new amd, intel, nvidia ids, updates to driver version etc.
+
+--------------------------------------------------------------------------------
+CHANGES:
+
+1. SHORT: for Memory:, switched to using MiB/GiB/TiB, these numbers are just
+getting too big to be readable. This is also dynamic, if both used and available
+are the same unit, shows x/y [unit], otherwise shows x [unit]/y [unit].
+
+2. MEMORY: changed gpu: to igpu: to avoid confusing it with standalone gpu.
+Since only raspberry pi had gpu ram data before, almost nobody would have seen
+this in general anyway.
+
+--------------------------------------------------------------------------------
+DOCUMENTATION:
+
+1. MAN/OPTIONS: Updated for -Bxx, battery power now.
+
+2. MAN: updated to better define where the System RAM: total:.. available etc
+come from, and what they refer to. Also added explanation in -m section about
+what the stuff is, and what the field names refer to.
+
+2a. DOCS: docs/inxi-ram.txt added, and more info moved from inxi-data.txt and
+inxi-resources.txt. Goal is to remove both those files and move all their data,
+and any new data, into granular inxi-xxx.txt files. Also moved some RAM data
+from inx-unit-handling.txt to inxi-ram.txt.
+
+2b. DOCS: docs/inxi-unit-handling.txt: updated with more ram / memory units,
+code, etc, to better fit with the concept of the inxi-unit-handling.txt doc.
+
+2c. DOCS: docs/inxi-partitions.txt: updated, added more sources for partition
+file system types, cleaned up, more useful as a reference now.
+
+2d. DOCS: docs/inxi-distros.txt: NEW, merged data from inxi-data.txt,
+inxi-resources.txt. Updated and added more info.
+
+2e. DOCS: docs/inxi-tools-mapping.txt split off from inxi-tools.txt, makes it
+easier to find the mapping functions and features, which are hard to remember.
+Also updated and improved its usability. This is kind of a key document because
+it's hard to remember all the mapping tools internally, and this also connects
+those tools to their relevant granular inxi-xxx.txt docs. Not that it will help
+get helpers for these tedious tasks, but one can always dream, can't one?
+
+3. DATA: data/graphics/ added for first vulkaninfo output file.
+
+--------------------------------------------------------------------------------
+CODE:
+
+1a. RAM: Fixed an irregularity, for RamItem, it used MiB as internal unit, this
+was silly because inxi uses KiB everywhere else. This correction was relatively
+easy to do, and allows the values to be used by other parts of inxi, like
+MemoryData.
+
+1b. RAM: Added return of ram total for memory.
+
+2a. INFO/RAM/PROCESSES: When MEMORY active, now uses row reference to create the
+fields. For INFO, now uses MemoryData::row() to generate the row fields instead
+of doing the logic in the info line generator. This simplifies the processing
+and allows for more granular control of output.
+
+2b. INFO/RAM/PROCESSES: Added debugger switches --dbg 53 (show raw KiB/count
+values for /sys/devices/system/memory and /proc/iomem. Added --dbg 54, which
+shows per line size for iomem, in human readable units, and a final summary
+report of iomem and /sys data, this speeds up debugging.
+
+2c. INFO/RAM/PROCESSES: Added --fake iomem, --fake sys-mem for debugging and
+testing.
+
+3. MEMORY: MemoryData::short_data(): added so one tool generates output for all
+sources for short data. Easier to track and make consistent, and to make more
+granular and robust.
+
+4. DRIVES/PARTITIONS: PartitionItem::partition_filters(),
+PartitionItem::fs_excludes(): refactored into PartitionItem::get_filters(),
+PartitionItem::set_filters(). Cleaned up, organized better, made comments much
+more useful. Goes with DOCS 2c updates. Now there's just one sub that does this
+filter/exclude work, which makes it easier to maintain long term.
+
+5. GLOBAL: Used a trick I just learned, declaring variables in the bracket scope
+of a class, but not inside the package/class declaration. This makes it work
+like a static variable, which Perl 5.008 doesn't support. You have to use a sub
+inside the bracket scope to return the data outside that scope, but that is easy
+to do.
+
+6. MACHINE: Added return of b_vm for VM detection in MEMORY.
+
+7. SYSTEM: CompilerVersion: Failed to properly use references when passing
+$compiler around, not actually sure why it worked, but now is consistent.
+
+--------------------------------------------------------------------------------
+-- Harald Hope - Mon, 10 July 2023 14:00:04 -0700
+
+================================================================================
Version: 3.3.27
Patch: 00
Date: 2023-05-07