¿De dónde obtiene uname su información?

¿De dónde obtiene uname su información?

¿De dónde obtiene realmente la información la uname?

Me imagino que esto es algo que debería ser sencillo. Desafortunadamente, no puedo encontrar ningún encabezado que contenga solo esa información.

Digamos que alguien quiere cambiar la salida básica de uname/ uname -s from Linuxa otra cosa (esencialmente, cambiar el nombre del kernel).

¿Cómo haría él/ella para hacerlo de la manera correcta (es decir, cambiando la fuente)?

Respuesta1

Los datos se almacenan en 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);

Las cadenas en sí están en include/generated/compile.h:

#define UTS_MACHINE "x86_64"
#define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"

y en include/generated/utsrelease.h:

#define UTS_RELEASE "3.14.0-v2-v"

UTS_SYSNAME se puede definir en include/linux/uts.h

#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif

o como #definir en archivos MAKE

Finalmente, el nombre de host y el nombre de dominio se pueden controlar mediante /proc/sys/kernel/{hostname,domainname}. Estos son por espacio de nombres UTS:

# hostname
hell
# unshare --uts /bin/bash
# echo test > /proc/sys/kernel/hostname 
# hostname
test
# exit
# hostname
hell

Respuesta2

La unameutilidad obtiene su información de la uname()llamada al sistema. Rellena una estructura como esta (verman 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
       };

Esto proviene directamente del kernel en ejecución. Supongo que toda la información está codificada, excepto quizás domainname(y resulta que también nodename, machiney release, ver comentarios). La cadena de lanzamiento, desde uname -r, se puede configurar mediante la configuración en el momento de la compilación, pero dudo mucho que el campo sysname pueda hacerlo: es el kernel de Linux y no hay ninguna razón concebible para que use algo más.

Sin embargo, dado que es de código abierto, puede cambiar el código fuente y recompilar el kernel para usar el nombre del sistema que desee.

Respuesta3

Con la ayuda de unReferencia cruzada de Linuxy tu mención de /proc/sys/kernel/ostype, seguí ostypehastaincluir/linux/sysctl.h, donde un comentario dice que los nombres se agregan llamando register_sysctl_table.

Entonces, ¿dónde está eso?llamado desde? un lugar eskernel/utsname_sysctl.c, que incluyeincluir/linux/uts.h, donde encontramos:

/*
 * Defines for what uname() should return 
 */
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif

Entonces, como eldocumentación del núcleoestados:

La única forma de ajustar estos valores es reconstruir el kernel.

:-)

Respuesta4

scripts/mkcompile_h

En v4.19, este es el archivo que genera include/generated/compile.hy contiene varias partes interesantes de /proc/version:https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_h

  • la #<version>parte proviene del .versionarchivo en el árbol de compilación, que se incrementa cada vez que ocurre un enlace (requiere cambios de archivo/configuración) mediante scripts/link-vmlinux.sh.

    Puede ser anulado por la KBUILD_BUILD_VERSIONvariable de entorno:

    if [ -z "$KBUILD_BUILD_VERSION" ]; then
        VERSION=$(cat .version 2>/dev/null || echo 1)
    else
        VERSION=$KBUILD_BUILD_VERSION
    fi
    
  • la fecha es solo una datellamada sin formato:

    if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
        TIMESTAMP=`date`
    else
        TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
    fi
    

    y de manera similar el nombre de usuario proviene de whoami( KBUILD_BUILD_USER) y el nombre de host de hostname( KBUILD_BUILD_HOST)

  • La versión del compilador proviene de gcc -v, y parece que no se puede controlar.

Aquí se muestra cómo cambiar la versión de la pregunta:https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot

información relacionada