How to discover the machine type? - linux

I would like to discover the machine architecture type of a big number of machines. I have the hostname of each machine. The machines have Debian 4 linux, SunOS 9, SunOS 10 or Apple Darwin. All are unix-like, but with minor differences.
I would like to know:
- architecture (x86, x86_64, ia64, sparc, powerpc...)
- processor type (intel pentium, pentium pro, pentium II, sparc, powerpc, itanium, athlon, core 2 duo, cytrix, etc...)
- number of processors
Beware, I want the "type" of the machine. The stupid approach using 'uname' does not work on Sun and it also returns things like 'i686' when the machine is in fact 'x86_64' but the operating system is 32 bits. /proc/cpuinfo doesn't work neither, and things get even more complicated because some machines dont have a C compiler installed (I'm sure they all have sh, perhaps python or perl, dunno).
Thanks in advance!! :)

arch ; uname -a
arch is the standard way to get the name of the CPU instruction set. uname -a gets a bunch of stuff about the OS. uname withouth the a gets the OS name.
However programmatically speaking, the equivalent to arch is uname -m.

You can try the following Perl one-liner:
perl -MConfig -e 'print "$Config{myarchname}\n";'
I know on Mac OS X Leopard with Perl 5.10.0 it prints "i386-darwin". I don't know of a way in Perl to get the actual processor name - your best bet is probably C since it's a fairly limited set of possibilities. You can get at a C compiler's predefined macros from Perl:
perl -MConfig -e 'print join("\n", split(/ /, $Config{cppsymbols})), "\n";'
This will list C macros like __LITTLE_ENDIAN__ and __MACH__ for Mach-O format and __i386__ (on Leopard at least), as well as the useless ones like __GNUC__ and __STDC__. Of course, all of this help assumes you have Perl on all machines. If not, I'm sure other languages have similar facilities to help you.

I would suggest you look at the facter component of the Puppet system. From the URL http://reductivelabs.com/projects/facter/.
A cross-platform Ruby library for retrieving facts from operating systems. Supports multiple resolution mechanisms, any of which can be restricted to working only on certain operating systems or environments. Facter is especially useful for retrieving things like operating system names, IP addresses, MAC addresses, and SSH keys.

Why /proc/cpuinfo doesn't work?
I don't know all of the OSs you mentioned, but I think it give quite detailed information under Linux. At least, with the model of CPU, other informations can be looked up from a data table.
The software can only see what the OS let it to see, so if the OS doesn't provide informations like /proc/cpuinfo, then you'll have no way to know it.
reply to the comments:
I am not saying look for /proc/cpuinfo for all the OS. It's a two steps method: first you find out which OS it is using uname, then look for the OS specific position for the cpu info.

This is not a complete answer, but it may help you reach your goal.
arch does not work on HP-UX Itanium, and it does not have the /proc filesystem, as you mentioned.
This explains how to determine the endianness (byte order) the O/S is using simply with shell commands. It works on at least 4 major Unixes (Linux x86_64, Solaris Sparc, AIX/Power, HP-UX Itanium). If you know the byte ordering you can deduce a lot about which CPU you're dealing with, based on this source.
For instance, if Solaris won't tell you the correct architecture, but you see that it's big endian, you at least know you're not on x86_64, and probably Sparc.
Finally, for Sparc you can do this to determine whether the OS is running in 32 or 64 bit mode:
# isalist -v
sparcv9+vis2 sparcv9+vis sparcv9 sparcv8plus+vis2 sparcv8plus+vis sparcv8plus sparcv8 sparcv8-fsmuld sparcv7 sparc
If it says 'sparcv9' it's 64 bit, sparcv8 is 32

The use of uname -a will bring you to much information, so you have to search for the information you want to have.
Just use:
uname -i
for the hardware platform
or
uname -m
for the machine hardware name

Related

Linux, CPU-architecture in which file stored

I like to know, in which file the value for the CPU architecture is stored on Linux e.g. x86_64.
I know several methods (shell commands) in order to access this value like lscpu or uname -a.
Furthermore I'm aware of the Qt-Method QSysInfo::currentCpuArchitecture(). And they all provide the required information.
But I like to create an OS-Interface which retrieves the information of the underlying operating system (in my case Linux) only by using "Linux-Tools" like information from files in /proc/....
I also know that I can run a shell command in my program by using popen() and access the results by the std streamer classes. That's no problem. But unfortunately we don't like run shell commands in our software.
I have looked in several files like
/proc/version, /proc/cpuinfo, /proc/devices or in files in subfolders of /proc.
But unfortunately it seems to me as if I always overlooked this piece of information. I'm sure that it has to be in a file because the method QSysInfo::currentCpuArchitecture() access this information, too.
So if somebody knows where this information is placed on Linux I would be happy if he or she let me know.
With kind regards
According man lscpu
lscpu gathers CPU architecture information from sysfs,
/proc/cpuinfo ...
looking for the information under /proc and cpuinfo was the right idea, since the information is there, but not in the format you were expecting. It is somehow "hidden" in line flags. You like to look for lm (long mode).
cat /proc/cpuinfo | grep "flags\| lm "
If the flag for long mode is set you are on x86_64.
Thanks / Credits to
What do the flags in /proc/cpuinfo mean?
CPUID, bit 29 (LM)
How the information is gathered and processed you can find in sys-utils/lscpu.c, in example from line 369-378.
Other CPU modes are
Real Mode, 16 bit CPU, Intel 8086 or 8080 emulation mode, all x86 CPU start in this mode after reset
Protected Mode, 32-bit CPU

Differences between arm "versions?" (ARMv7 only)

Basically I would like to know the difference between ARMv7l and ARMv7hl?
I got a arm processor with armv7l and there are a lot of rpm's for armv7hl.
I don't exactly know what I have to search for to get information about that.
What is this "suffix" called? Are there any other types? What are they doing differently?
I would assume that it's indicating packages compiled for little-endian and hard-float ABI as appropriate - i.e. it's a software thing and only tangentially related to the hardware.
In other words, you don't actually have an "armv7l" processor - you have an ARMv7 processor which may well have a hardware FPU (and can run big-endian if you really wanted to), but you happen to be running a soft-float userspace that doesn't rely on one being present - just like running an i686 distribution doesn't imply you're not on an x86_64 machine. Different Linux distributions have different names for their various ports but some trivial poking around suggests this case might be openSUSE's convention.

Determine dynamically linux OS architecture

Is there is a way to know dynamically Linux architecture, whether it x86-64 or x86?
The Posix standard uname function (implemented in the uname(2) syscall) is dynamically giving you the information about the CPU. You probably want the machine field.
Caution about x86-64 kernels running a 32 bit program (e.g. a 32 bits Debian distribution chroot-ed in a 64 bits Debian, or perhaps a 32 bits ELF binary running on a 64 bits system); I have no idea what they give in that situation; I would imagine some x86_64 in that case, since the kernel does not really know about the binaries and libc of the system.
See also the Linux specific personality(2) syscall.
Google is your friend: http://sourceforge.net/p/predef/wiki/Architectures/
You want to test for the macros __amd64__ and __i386__. Ideally, you don't test the macros at all and write correct, portable code.
You can use lscpu command to list characteristics about CPU.

Executing Binary Files

I downloaded a binary file that was compiled (a C program) using GCC 4.4.4 for x86-64 Red Hat Linux.
Is it normal that when I try to run it on a Mac OS X (running Lion so also x86-64) running GCC 4.2.1 that it would say: cannot execute binary file? It can't detect it as a binary file.
Why would it do that? I believe the gcc version has nothing to do with that since the file has already been compiled. It has been compiled for x86-64 of which both machines run. Can someone please explain?
There are different binary formats. Linux systems use ELF for executables and libraries, but Mac OS X uses the Mach-O format. Windows uses another still: PE format.
It's highly unlikely that a binary compiled for a particular OS will run on another. Either get a binary for Mac, or get the source and compile it yourself.
There are many things that will cause issues - version of libc and libstdc++, there can be difference in versions of .so libraries - different API interface to the OS itself. Or even a different binary format (ie VMS binaries do not run on AIX).
Although Rad Hat Linux and Mac OS X are both 'Unix based', they cannot run each other's binaries. Just like you can't run Windows binaries on Macs and vice versa.
binaries in this sense are compiled to make operating system calls, when your program has a printf() that boils down to operating system calls. If the operating system it was compiled for is say a 64 bit redhat linux then that likely means the binary is going to look for redhat linux names for shared libraries in redhat linux paths. Which has absolutely nothing in any way shape or form to do with a completely different operating system, Mac OS X, and its system calls and shared or static libraries, etc. Its like taking a wheel off of a mini cooper and trying to bolt it onto a bicycle. Yes at one point in time it was raw metal and rubber, and could have been formed into a bike tire. But once you make that binary, the car tire or the bike tire, that is what it is. sometimes you find an emulator like wine that emulates windows on top of a posix system. or a virtual machine like vmware that lets you run a whole different operating system on top of another by virtualizing a whole computer.
it is also true that you cannot generally expect to take any old C program and have it compile and run on any operating system that say has a gcc compiler. yes you can learn to write c programs that are portable, but you have to carefully stick to libraries that are supported on all the target platforms. so even taking the source code for your program to the mac and compiling it is not necessarily going to just work.

How can I know if I am running in a 64bits or a 32bits linux from within a perl script?

I don't want to directly access the shell (for example to use uname). I am looking for a fast-forward way to detect the architecture (only if it is 32 or 64 bits), once I know I am on linux.
There are 3 separate questions you could be asking:
Note for all that there's not a single magic "64-bit", there's lots of different things that could mean.
What's the hardware? -- /proc/cpuinfo contains this info in a hard to parse manner. You basically need to have a table of what the different CPUs are. I believe you'll get numbers bigger than 32 in an "address sizes" if the kernel is 64-bit, though.
What's the OS/kernel? -- I believe use POSIX; and inspecting (POSIX::uname())[4] is the canonical answer, but -d /lib64, -d /usr/lib64 being true is also a good indicator.
Is this a 64-bit perl? -- use Config; and look at $Config{archname}, $Config{myarchname}, $Config{use64bitint}, or some other variable in Config that matches up to what you believe "64 bit" means.
perl -e 'use Config; print $Config{longsize}';
Will return 8 bytes on a 64 bit implementation of Perl, and 4 bytes on a 32 bit implementation of Perl.
If you want to actually check the hardware, you'll have to either do a uname or check for something that only reasonably exists on a 64 bit machine (like /lib64). Note that it is often not very useful to know the hardware support for 64 bits if you are stuck in a 32 bit application.

Resources