Would this help for machine code?
I noticed that inxi will not display any machine information for any server chassis I test it on. This is the code I have been using for a while for my own bash script, it works on really old server hardware as well as the latest and greatest. The dmidecode information works for all Dell, HP (Compaq), IBM and Sun x86 chassis. It may not help inxi in the slightest but here it is. :)
:: Code ::
# Grab hardware information. VENDOR=$(dmidecode | grep -m 1 Vendor | awk '{ print $2 }') PRODUCT=$(dmidecode | grep -m 1 Product | awk '{sub("^[[:space:]]*Product Name: ", "", $0); print $0}') # Sun and some very old HP servers do not fill in the first Vendor field with Sun Microsystems or HP if [ "${VENDOR}" = "American" ]; then VENDOR="Sun" elif [ "${VENDOR}" = "Phoenix" ]; then VENDOR="HP" fi SERIAL="" if [ ${VENDOR} = "Dell" ]; then SERIAL=$(dmidecode | grep -m 1 "Serial Number" | awk '{ print $NF }' | egrep ^[0-9A-Z]{7}$ | sort | uniq) elif [ "${VENDOR}" = "Compaq" -o "${VENDOR}" = "HP" ]; then SERIAL=$(dmidecode | grep -m 1 "Serial Number" | grep -v "Specified" | awk '{ print $NF }' | uniq) elif [ "${VENDOR}" = "Sun" ]; then SERIAL=$(dmidecode | grep -m 1 "Serial Number" | awk '{ print $NF }' | sort | uniq) # Some IBM servers list the CPU and RAM prior to listing the System's Serial number. elif [ "${VENDOR}" = "IBM" ]; then SERIAL=$(dmidecode | grep -A 4 "System Information" | grep -m 1 "Serial Number" | awk '{ print $3 }') else echo "Unknown" fi # Check if the serial number is all zero's (SunFire 4100 issue) if [ $(echo ${SERIAL} | egrep ^0+$ | wc -l) -gt 0 ]; then SERIAL="INVALID" fi Back to top |
Wanted to add that versions of dmidecode after 2.10 allow greater control over chassis information. Such as:
# dmidecode -s system-serial-number USE1234567 # dmidecode -s system-product-name ProLiant DL380 G5 Since a lot of the hardware I work with in our data centers can be up to 10 years old, with old OS's, the above is not an option. I found on older hardware using the -t<number> flag was unreliable and that using grep/awk to parse the information was almost 100% reliable. Back to top |
Please verify that inxi shows no machine information when run as root for those machines.
inxi already uses dmidecode if no /sys directory is detected, but it must be run as root. <update> I see the inxi issue, it uses dmidecode -s <option> Can you verify for me that: :: Code :: dmidecode -s system-version && echo works || echo failsreturns error? That way I can test for error on that and then fallback to using your basic method. inxi already tests for the case where dmidecode is installed but no smbios/dmi decode data is available, but it's just a matter of adding in another test before the main dmidecode -s set runs. Please note that inxi uses in this order these options, in order to create an array in this order, so whatever fallback method would have to handle that. I suggest posting or sending me a link in private to the full output of dmidecode for one of these older machines, ideally for all of them since I have no data sets for that type of machine, and I can inject it directly for testing and debugging, much easier than going back and forth here trying to see if something works. ie, for each machine: :: Code :: #dmidecode > machinetype-dmidata.txt:: Code :: local machine_files="
sys_vendor product_name product_version product_serial product_uuid board_vendor board_name board_version board_serial bios_vendor bios_version bios_date " local dmi_names=" system-manufacturer system-product-name system-version system-serial-number system-uuid baseboard-manufacturer baseboard-product-name baseboard-version baseboard-serial-number bios-vendor bios-version bios-release-date " To be clear, this issue / suggestion is accepted, but requires real world machine dmidecode datasets for me to actually create a fix that will work in all cases. Issues like this, in fact, will always be accepted, because inxi should work in as many cases as we can make it work. Back to top |
:: Code :: dmidecode -s system-version && echo works || echo failsI ran the code above on 18 machines ranging from Dell 2650's to Dell R720's, on HP DL580 G2's to DL585 G7's, and a couple IBM 3850's. The majority of the servers were running a version of RHEL and one FreeBSD 8.2 box I use as a workstation. The servers pretty much spit out the same information: Results for dmidecode version 2.11: Not Specified works Results for dmidecode version 2.10 and earlier: fails However, when I ran the code on the FreeBSD workstation, which was running dmidecode 2.10, the -s system-version was an available option. So, it looks like it depends on which options have been back-ported on which OS. Perhaps run a two fold check. Once for the version of dmidecode being used, and then again to see what -s flags are supported. I will gladly send you dmidecodes for various hardware/OS versions. I will just remove their serial numbers. ;D Back to top |
you can ignore all bsd/unix type systems, inxi doesn't support unix, we tried very early but it's just not practical, too much linux only stuff runs in inxi to make it possible to port.
To be practical the test needs to be simple, keep in mind this is now the third fallback being used, so it doesn't need to be perfect, just decent. If all your linux systems running dmidecode 2.10 or older show fail error, ie, if I do a test: ! dmi -s option or whatever, then that's good enough I'd say. what does: dmidecode -s system-version || echo $? show on such a system? I'm just looking for a quick and dirty test, it doesn't have to be 100% perfect, just fast. Very few systems will trigger this level now so all it needs to do is be enough to catch all the linux stuff in a simple test. In inxi, I try to avoid testing app versions (it may show them, but that's just string data), it gets messy, too much to track over time, best to test the actual outcomes of operations, if they fail, then fall back, etc. Back to top |
the dmidecode data looks pretty good, it looks like we can get a full report from it, with some painful gawk manipulations, but nothing out of the usual for inxi, sad to say.
I don't see any serial number data though, so you might not get that. I also see a possible way to finally get -m running, which will be inxi 1.9, -m will be memory report, ideally would work as regular user, but dmidecode needs root, but I think that's ok. I'd been hoping /sys would reveal the actual ram data, but it looks like it won't, so if -m is ever to be implemented, I think it will be done via dmidecode. I'll watch the -t option however as well to simplify the parsing of the data for memory, not related to your issue however, but I suspect I'll use similar methods, but if you say -t isn't reliable, then maybe it would be best to just directly parse the output. On the bright side, dmidecode is very fast, so there's no problem using it in inxi, unlike some other hardware reporting tools. Just out of curiousity, and not related to your issue, what does: dmidecode -t 6 show on older systems? Is it reliable? it's a lot easier to parse a small amount of data than a large amount. Back to top |
Great! The serial number data is there, however, I removed the numbers from the ones I sent you. :D Just to protect client boxes, you know just in case. :D
I am getting some mixed output on the dmidecode -t6. I will do some more testing before I post my results. Below is a simple script I use to verify the results of dmidecode, as well as the "agent" software provided by Dell and HP. It may be helpful since /sys does not show all the ram data you need. I also had my CPU double check code there as well. Hope it helps. :) Will post my dmidecode -t6 data for you tomorrow. :: Code ::
# Parse out memory info. RAM_ADD_TOTAL="" RAM_PER_BANK="" RAM_BANKS=0 RAM_UNITS=$(dmidecode | grep "Maximum Capacity" | awk '{ print $4 }' | sort | uniq) for ramentry in $(dmidecode | grep "Maximum Capacity" | awk '{ print $3 }') do RAM_ADD_TOTAL=$(($RAM_ADD_TOTAL + $ramentry)) RAM_BANKS=$((RAM_BANKS + 1)) RAM_FOR_THIS_BANK="" RAM_FOR_THIS_BANK="$(dmidecode | grep "Maximum Capacity" | grep -n "Maximum Capacity" | grep -w ^${RAM_BANKS} | awk -F: '{ print $3 }' | awk '{ print $1 $2 }')" RAM_PER_BANK="${RAM_PER_BANK} Bank ${RAM_BANKS} Capacity: ${RAM_FOR_THIS_BANK}" done USEDRAM=$(free -mto | grep Mem: | awk '{ print $3 "MB" }') FREERAM=$(free -mto | grep Mem: | awk '{ print $4 "MB" }') TOTALRAM=$(free -mto | grep Mem: | awk '{ print $2 "MB" }') CPU_COUNT=$(grep processor /proc/cpuinfo | wc -l) CPU_MODEL=$(grep -m 1 "model name" /proc/cpuinfo | awk '{ print $4" "$5" "$7 }') CPU_CACHE=$(grep -m 1 "cache size" /proc/cpuinfo | awk '{ print $4 $5 }') CPU_SPEED=$(grep -m 1 "cpu MHz" /proc/cpuinfo | awk '{ print $4 $5 "MHz"}') TOTALPROC=$(ps axue | grep -vE "^USER|grep|ps" | wc -l) <edit> I forgot to add the dmidecode -s system-version info. On some machines/OS versions it reported back "Not specified" and on others it would state "Invalid string keyword: system-version". It seems system-version is geared more to desktop chassis as opposed to server chassis, but don't quote me on that. :D Back to top |
I just remembered a trick I do sometimes for cases where the data is not right in terms of structure, insert a linebreak before the line that is supposed to results.
What inxi will do, when I get around to it, is loop through each item and then grab the proper field from it, item by item. Once the machine logic for your systems works, instituting the logic for ram would be very similar, which is why I want to find the method that works most universally, to avoid having to do multiple methods if possible. I do need the other stuff I asked: dmidecode -s system-version || echo $? Note specifically this is returning only error values which is easy to then test. to see what I'm actually going to look for in error messages. So far it looks like inxi can just dump the Handle line completely then look for each actual category name, then parse that to get the specific fields, that should work I believe. Replacing the handle line with an empty line will also create a blank line, which is what we want to separate results. Back to top |
I'm glad you gave me 4 different dmidecode outputs, I'm seeing key differences between them
:: Code :: # this is standard and corresponds to what you see now
SMBIOS 2.5 present. 67 structures occupying 3419 bytes. Table at 0xBFB9C000. Handle 0xDA00, DMI type 218, 11 bytes OEM-specific Type Header and Data: DA 0B 00 DA B2 00 17 00 0E 20 00 # but this is significantly different: # dmidecode 2.2 SMBIOS 2.3 present. 56 structures occupying 1977 bytes. Table at 0x000FB320. Handle 0xDA00 DMI type 218, 11 bytes. OEM-specific Type Header And Data: DA 0B 00 DA B0 00 17 03 08 28 00 as you can see, the line after Handle in type one is not indented, and has an empty line between Handle and previous item, but the line after Handle in the second is indented, and there's no empty line before Handle line. I'll see how to pretreat this data to make sure such differences do not impact the results. So the dmidecode data will definitely need pretreatment, which is fine, I do that in other system output functions too to make sure the actual structures are the same for all systems, but good to skip that step and include that requirement in the design from the start. Back to top |
The output will not return any exit code. See below.
:: Code ::
[root@sh ]# dmidecode -s system-version || echo $? Not Specified [root@sh ]# [root@sh ]# dmidecode -s system-version Not Specified [root@sh ]# <edit> Even though the man page for dmidecode 2.11 clearly states: "If KEYWORD is not provided or not valid, a list of all valid keywords is printed and dmidecode exits with an error." I believe they mean a text error as opposed to an exit code of 0, 1, 2 etc. Back to top |
All times are GMT - 8 Hours |