Da dove "uname" sta estraendo informazioni?


Risposte:


31

unameusa la chiamata di sistema uname(2)per ottenere le informazioni relative al kernel che mostra.

La sinossi è:

#include <sys/utsname.h>
int uname(struct utsname *buf);

dove uname(2)restituisce informazioni nella struttura indicata da buf. Inoltre è possibile leggere il file di intestazione utsname.hda /usr/include/"$(arch)"-linux-gnu/sys/utsname.hscavare più a fondo.

Dai un'occhiata man 2 unameper avere più idea a riguardo.


quando eseguo "uname -i", l'output è "x86_64". Quando incrociamo "/usr/include/x86_64-linux-gnu/sys/utsname.h", non vedo nulla che faccia riferimento a "x86_64". Ho fatto riferimento a "man 2 uname" e afferma che parte delle informazioni sul nome utente sono referenziate tramite "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {versione} e {domainname}" il problema è che nessuno di quei file fa riferimento a qualcosa che indica "x86_64". Qualche altro consiglio?
Roy Hernandez,

@RoyHernandez Qual è l'output di locate --regex '^/usr/include/.*/sys/utsname.h$'?
heemayl

L'output è: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Roy Hernandez,

@RoyHernandez Questo dice che il file esiste e che stavi facendo qualcosa di sbagliato ..
heemayl

Quando eseguo un uname -ioutput è x86_64. Quando eseguo locate --regex '^/usr/include/.*/sys/utsname.h$'l'output ritorna/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez il

22

Il programma straceci consente di visualizzare le chiamate di sistema che un'applicazione può effettuare. Con uname -aè evidente che le sole openchiamate vanno a librerie di sistema, quindi tecnicamente non c'è alcun file sul filesystem che la unameapre per la lettura. Piuttosto effettua chiamate di sistema usando le librerie C.

Come ha correttamente sottolineato Heemayl, esiste una chiamata di sistema per recuperare le informazioni memorizzate nella unamestruttura. È la pagina man, suggerisce quanto segue:

Questa è una chiamata di sistema e il sistema operativo presumibilmente conosce il suo nome, versione e versione. . . . . . Parte delle informazioni sull'utsname sono accessibili anche tramite / proc / sys / ker-nel / {ostype, hostname, osrelease, versione, domainname}.

Parte delle informazioni sull'utsname sono accessibili anche tramite / proc / sys / ker-nel / {ostype, hostname, osrelease, versione, domainname}.

/procil filesystem tuttavia è virtuale, nel senso che esiste solo mentre il sistema operativo è in esecuzione. Pertanto, per alcuni aspetti, è impostato all'interno delle librerie del kernel o del sistema.

Infine, leggendo il codice sorgente di uname.ccui è possibile ottenere apt-get source coreutils, possiamo vedere che utilizza effettivamente la utsname.hlibreria (stampata con numeri di riga):

 19 
 20 #include <config.h>
 21 #include <stdio.h>
 22 #include <sys/types.h>
 23 #include <sys/utsname.h>
 24 #include <getopt.h>
 25 

strace produzione:

skolodya@ubuntu:$ strace uname -a
execve("/bin/uname", ["uname", "-a"], [/* 58 vars */]) = 0
brk(0)                                  = 0x1478000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6935000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=137226, ...}) = 0
mmap(NULL, 137226, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7efee6913000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0
mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7efee6350000
mprotect(0x7efee650b000, 2093056, PROT_NONE) = 0
mmap(0x7efee670a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7efee670a000
mmap(0x7efee6710000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7efee6710000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6912000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6910000
arch_prctl(ARCH_SET_FS, 0x7efee6910740) = 0
mprotect(0x7efee670a000, 16384, PROT_READ) = 0
mprotect(0x606000, 4096, PROT_READ)     = 0
mprotect(0x7efee6937000, 4096, PROT_READ) = 0
munmap(0x7efee6913000, 137226)          = 0
brk(0)                                  = 0x1478000
brk(0x1499000)                          = 0x1499000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=7216688, ...}) = 0
mmap(NULL, 7216688, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7efee5c6e000
close(3)                                = 0
uname({sys="Linux", node="eagle", ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6934000
uname({sys="Linux", node="eagle", ...}) = 0
uname({sys="Linux", node="eagle", ...}) = 0
write(1, "Linux eagle 4.1.0-040100rc2-gene"..., 113Linux eagle 4.1.0-040100rc2-generic #201505032335 SMP Mon May 4 03:36:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
) = 113
close(1)                                = 0
munmap(0x7efee6934000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

quando eseguo "uname -i", l'output è "x86_64". Quando incrociamo "/usr/include/x86_64-linux-gnu/sys/utsname.h", non vedo nulla che faccia riferimento a "x86_64". Ho fatto riferimento a "man 2 uname" e afferma che parte delle informazioni sul nome utente sono referenziate tramite "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {versione} e {domainname}" il problema è che nessuno di quei file fa riferimento a qualcosa che indica "x86_64". Altre raccomandazioni?
Roy Hernandez,

@RoyHernandez In C è possibile determinare l'architettura di una CPU in base alle dimensioni dell'intero, ad esempio - fare riferimento qui . Quindi uname.cnon è necessario necessariamente utilizzare una libreria per questo - possiamo sicuramente vedere il codice sorgente, per essere sicuri.
Sergiy Kolodyazhnyy,

In realtà, si basa su una libreria. . . machine.h
Sergiy Kolodyazhnyy,

machine.hsembra essere disseminato in tutto il sistema. Su quale machine.hfile si basa?
Roy Hernandez,

@RoyHernandez tutti gli elenchi machine.hsul mio sistema sembrano essere nella /usr/src/linux-headers-3.19.0-33directory. È molto probabile che usi la libreria fornita dal kernel attualmente in esecuzione
Sergiy Kolodyazhnyy,

6

Naturalmente la risposta di Heemayl è corretta.

Solo per divertimento, ecco uno snippet C funzionante che mostra i dati restituiti da uname()(una specie di fatto in casa unamese vuoi): compilarlo con gcc uname.c -o unameed eseguirlo con ./uname:

#include <stdio.h> // printf()
#include <sys/utsname.h> // uname()

int main() {
        int ret; // stores the return value of uname()
        struct utsname utsname; // stores the data returned by uname()
        struct utsname *utsname_ptr = &utsname; // pointer to the struct holding the data returned by uname()

        ret = uname(utsname_ptr); // calls uname() on utsname_ptr and stores its return value in ret

        /* prints the fields of utsname */

        printf("%s\n", utsname.sysname);
        printf("%s\n", utsname.nodename);
        printf("%s\n", utsname.release);
        printf("%s\n", utsname.version);
        printf("%s\n", utsname.machine);

        /* returns the return value of uname() */

        return(ret);
}
% ./uname 
Linux
user-X550CL
4.2.0-25-generic
#30-Ubuntu SMP Mon Jan 18 12:31:50 UTC 2016
x86_64

da dove printf("%\n", utsname.machine);proviene la sua informazione?
Roy Hernandez,

@RoyHernandez Dalla struttura utsname, che viene popolata durante la chiamata a uname(). L'esempio probabilmente non è troppo semplice per chi non ha le basi di C, ma ecco cosa succede più o meno: viene dichiarato un struct(tipo di dati C) di tipo utsnamedenominato utsname(tipo definito in <sys/utsname.h>); quindi utsname_ptrviene dichiarato un puntatore al suo nome (poiché uname()accetta un puntatore a un structtipo utsnamecome argomento, anche se questo avrebbe potuto essere evitato in questo caso, ma questa è un'altra storia).
kos

Quindi la chiamata a uname()ha l'effetto di popolare la struttura utsname, che al momento della printf()chiamata contiene i vari valori all'interno dei vari campi. Sfortunatamente, se non si ha familiarità con C, questo probabilmente non sarà facile da comprendere nei dettagli, ma il punto è che uname()popola una struttura di dati costruita appositamente, i cui campi vengono successivamente stampati tramite printf().
kos,

4

In aggiunta alla risposta di heemayl, puoi ottenere alcune informazioni come nel unamecomando da /proc/version.


/ proc / version contiene "Linux version 3.19.0-47-generic (buildd @ lgw01-19) (gcc versione 4.8.2 (Ubuntu 4.8.2-19ubuntu1)) # 53 ~ 14.04.1-Ubuntu SMP lun 18 gen 16 : 09: 14 UTC 2016 "e" uname -i "l'output è" x86_64 ".
Roy Hernandez,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.