
De onde o uname realmente obtém suas informações?
Eu acho que isso é algo que deve ser simples. Infelizmente, não consigo encontrar nenhum cabeçalho contendo apenas essas informações.
Digamos que alguém queira alterar a saída básica de uname
/ uname -s
de Linux
para outra coisa (essencialmente, renomeando o kernel).
Como ele/ela faria isso da maneira correta (isto é, mudando a fonte)?
Responder1
Os dados são armazenados em init/version.c:
struct uts_namespace init_uts_ns = {
.kref = {
.refcount = ATOMIC_INIT(2),
},
.name = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
.user_ns = &init_user_ns,
.proc_inum = PROC_UTS_INIT_INO,
};
EXPORT_SYMBOL_GPL(init_uts_ns);
As próprias strings estão em include/generated/compile.h:
#define UTS_MACHINE "x86_64"
#define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"
e em include/generated/utsrelease.h:
#define UTS_RELEASE "3.14.0-v2-v"
UTS_SYSNAME pode ser definido em include/linux/uts.h
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif
ou como #define em makefiles
Finalmente, o nome do host e o nome do domínio podem ser controlados por /proc/sys/kernel/{hostname,domainname}. Estes são por namespace UTS:
# hostname
hell
# unshare --uts /bin/bash
# echo test > /proc/sys/kernel/hostname
# hostname
test
# exit
# hostname
hell
Responder2
O uname
utilitário obtém suas informações da uname()
chamada do sistema. Ele preenche uma estrutura como esta (vejaman 2 uname
):
struct utsname {
char sysname[]; /* Operating system name (e.g., "Linux") */
char nodename[]; /* Name within "some implementation-defined
network" */
char release[]; /* Operating system release (e.g., "2.6.28") */
char version[]; /* Operating system version */
char machine[]; /* Hardware identifier */
#ifdef _GNU_SOURCE
char domainname[]; /* NIS or YP domain name */
#endif
};
Isso vem diretamente do kernel em execução. Eu presumiria que todas as informações estão codificadas nele, exceto talvez domainname
(e, como se vê, também nodename
, machine
e release
, veja os comentários). A string de lançamento, from uname -r
, pode ser definida através da configuração em tempo de compilação, mas duvido muito que o campo sysname possa - é o kernel do Linux e não há nenhuma razão concebível para ele usar qualquer outra coisa.
No entanto, como é de código aberto, você pode alterar o código-fonte e recompilar o kernel para usar qualquer nome de sistema que desejar.
Responder3
Com a ajuda de umReferência Cruzada do Linuxe sua menção a /proc/sys/kernel/ostype
, eu rastreei ostype
parainclude/linux/sysctl.h, onde um comentário diz que os nomes são adicionados chamando register_sysctl_table
.
Então, onde é issochamado de? Um lugar ékernel/utsname_sysctl.c, que incluiinclude/linux/uts.h, onde encontramos:
/* * Defines for what uname() should return */ #ifndef UTS_SYSNAME #define UTS_SYSNAME "Linux" #endif
Então, como odocumentação do kernelafirma:
A única maneira de ajustar esses valores é reconstruir o kernel
:-)
Responder4
scripts/mkcompile_h
Na v4.19, este é o arquivo que gera include/generated/compile.h
e contém várias partes interessantes de /proc/version
:https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_h
a
#<version>
parte vem do.version
arquivo na árvore de construção, que é incrementada sempre que o link acontece (requer alterações de arquivo/configuração) porscripts/link-vmlinux.sh
.Pode ser substituído pela
KBUILD_BUILD_VERSION
variável de ambiente:if [ -z "$KBUILD_BUILD_VERSION" ]; then VERSION=$(cat .version 2>/dev/null || echo 1) else VERSION=$KBUILD_BUILD_VERSION fi
a data é apenas uma
date
chamada bruta:if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then TIMESTAMP=`date` else TIMESTAMP=$KBUILD_BUILD_TIMESTAMP fi
e da mesma forma o nome de usuário vem de
whoami
(KBUILD_BUILD_USER
) e o nome do host dehostname
(KBUILD_BUILD_HOST
)A versão do compilador vem de
gcc -v
e não pode ser controlada, ao que parece.
Aqui está como alterar a versão da pergunta:https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot