De onde o uname obtém suas informações?

De onde o uname obtém suas informações?

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 Linuxpara 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 unameutilitá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, machinee 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 ostypeparainclude/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.he 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 .versionarquivo na árvore de construção, que é incrementada sempre que o link acontece (requer alterações de arquivo/configuração) por scripts/link-vmlinux.sh.

    Pode ser substituído pela KBUILD_BUILD_VERSIONvariá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 datechamada 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 de hostname( KBUILD_BUILD_HOST)

  • A versão do compilador vem de gcc -ve 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

informação relacionada