job.answiz.com
  • 9
Votes
name
name Punditsdkoslkdosdkoskdo

Where does uname get its data from?

Where does uname really get its information from?

I figure this is something that should be straightforward. Unfortunately, I can't find any header containing just that information.

Say someone wanted to change the basic output of uname/uname -s from Linux to something else (essentially, renaming the kernel).

How would he/she go about doing that the proper way (that is, changing the source)?

While I couldn't find anything in the source to indicate this, I believe it uses the uname syscall.

man 2 uname

should tell you more about it. If that's the case it's getting the information directly from the kernel and changing it would probably require recompilation.

You could change the binary for you uname to do whatever you want though, just write over it with w/e program you please. The downside being some scripts rely on that output.

  • 0
Reply Report

The data is stored in 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);

The strings themselves are in include/generated/compile.h:

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

and in include/generated/utsrelease.h:

#define UTS_RELEASE "3.14.0-v2-v"

UTS_SYSNAME may be defined in include/linux/uts.h

#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif

or as a #define in makefiles

Finally, the hostname and domainname can be controlled by /proc/sys/kernel/{hostname,domainname}. These are per UTS namespace:

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

The uname utility gets its information from the uname() system call. It populates a struct like this (see man 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
       };

This comes directly from the running kernel. I would assume all of the information is hard-coded into it, except perhaps domainname (and as it turns out, also nodenamemachine, and release, see comments). The release string, from uname -r, can be set via configuration at compile time, but I doubt very much the sysname field can -- it's the Linux kernel and there's no conceivable reason for it to use anything else.

However, since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want.

  • 0
Reply Report