Linux – Where does `hostname` store the hostname that I’ve set

hostnamelinux

This is quite puzzling. Does anyone know where the hostname command stores and reads hostname from?

I thought it was /etc/hostname but there is no such file on this Linux system that I'm using. I tried using strace to find where it was located but no read calls returned this information:

$ strace hostname 2>&1 | grep read
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340^\0\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\30\2\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\16\0\0\0\0\0\0"..., 832) = 832
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 248
read(3, "", 1024)                       = 0

Then I noticed it did uname syscall that returned this information:

uname({sys="Linux", node="server-name", ...}) = 0

A recursive grep in /etc/ returns nothing:

grep "server-name" -r /etc 

Where does uname store this information? Just in memory?

Best Answer

Take a look at this related U&L Q&A titled: Where does uname get its information from?. Information such as the hostname persists within a data structure within the Linux kernel, while the system is running. During a system's boot this information can be reattained through a variety of mechanisms that is typically distro specific.

If you look at the man 2 uname man page there's a data structure mentioned there:

           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
           };

The 2nd element of that structure, nodename[] is one place where the hostname is stored within the Linux kernel.

/proc

If you take a look at /proc/sys/kernel/hostname, the hostname is exposed here as well. This is a virtual location, /proc, but it does give you an alternative method for accessing the hostname. The system's domainname is here too, /proc/sys/kernel/domainname.

NOTE: Of interest, these values are UTS namespace specific.

Example

$ sudo hostname
oldhost
$ sudo unshare --uts /bin/bash
$ sudo echo newhost > /proc/sys/kernel/hostname 
$ hostname
newhost
$ exit
$ hostname
oldhost

Manipulating the hostname

On system's with Systemd you can use the cli tool hostnamectl to get/set the hostname. This will change it permanently between reboots.

$ sudo hostnamectl set-hostname --static somehostname

You can also find out it's value through sysctl:

$ sudo sysctl -a | grep kernel.hostname
kernel.hostname = myhostname

For Fedora releases, this ask.fedoraproject.org Q&A covers the topic pretty thoroughly, titled: Correctly setting the hostname - Fedora 20 on Amazon EC2.

Related Question