If you are on Fedora / RHEL / CentOS, the hostname is set by the rc.sysinit script after retrieving the desired value from the /etc/sysconfig/network file.
As to why it can only be changed once per boot - it can be changed anytime. You have to provide a new hostname to the hostname
command to change it, just editing a file won't do so. Keep in mind though that if you change it this way, any programs that were running before you changed it may still have the old value cached.
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.
Best Answer
That's for RHEL 7 that is.