我正在使用具有3个不同Linux分区的嵌入式Linux设备。最终用途选择从哪个分区引导。根文件系统是只读的。有一个以读写方式挂载的第4个分区。我需要所有Linux实例与DNS服务器(I.E.使用相同的主机名)使用相同的名称。创建文件系统时将不知道主机名,并且由于每个设备都需要唯一的主机名,因此稍后会分配主机名。我所做的是在读写分区上创建一个文件,该文件将在以后重写。然后我将/ etc / hostname更改为该文件的符号链接。我知道在读写分区已经安装之前无法读取文件,我相信这是我的问题。如果我将/ etc / hostname设置为普通文件,那么该文件中指定的任何内容都可以正常工作。更改/ etc / hosts似乎没什么用。
期望的结果是在WiFi连接时控制向DNS服务器注册的名称。我发现控制它的唯一方法是通过主机名。 / etc / hosts文件似乎不会影响它。如果主机名文件不可读或未设置,则Linux将其默认为“localhost”,并且不会注册任何对DNS有用的内容。
启动后运行的应用程序通过rfkill启用WiFi。在启用WiFi之前在脚本中运行某些东西是一种可能的解决方案。通过在启用WiFi之前更改命令行上的主机名,我无法成功更改DNS注册的内容。我可以更改主机名,但在DNS注册的内容不会更改。
的信息:
Linux内核是3.14.60,是基于yocto的构建。
systemd在启动时管理服务。
当前/ etc / hosts
127.0.0.1 ABC123.localdomain ABC123
当前/ etc / hostname
SerialNumberGoesHere
以下是启动后查看主机名的所有方法:
>hostname
localhost
>hostnamectl status
Static hostname: SerialNumberGoesHere
Transient hostname: localhost
Icon name: computer
Machine ID: 4cdac8e5dce348d2bfc133dd393f6172
Boot ID: 9b8c9da934e748fc86606c4a24f57f9e
Operating System: Linux
Kernel: Linux 3.14.60+g02d9429
Architecture: arm
>uname -n
localhost
>echo /proc/sys/kernel/hostname
localhost
>sysctl kernel.hostname
kernel.hostname = localhost
正如您所看到的,“hostnamectl status”会选择正确的静态主机名,但内核却没有。
在设备上
>nslookup 192.168.12.238
Server: 192.168.12.6
Address 1: 192.168.12.6 dc1.hq.com
Name: 192.168.12.238
Address 1: 192.168.12.238 linux.local
在另一台计算机上(Ping 192.168.12.238有效)
>nslookup 192.168.12.238
Server: 127.0.1.1
Address: 127.0.1.1#53
** server can't find 238.12.168.192.in-addr.arpa: NXDOMAIN
如果我将主机名符号链接更改为实际文件,则这是所需的结果:
>hostname
SerialNumberGoesHere
>hostnamectl status
Static hostname: SerialNumberGoesHere
Icon name: computer
Machine ID: 4cdac8e5dce348d2bfc133dd393f6172
Boot ID: ed760b42b7ae414881bc2d9352a8bb82
Operating System: ARANZ Sugar-Free Silhouette Star M2 (fido)
Kernel: Linux 3.14.60+g02d9429
Architecture: arm
>uname -n
SerialNumberGoesHere
>echo /proc/sys/kernel/hostname
SerialNumberGoesHere
>sysctl kernel.hostname
kernel.hostname = SerialNumberGoesHere
在设备上
> nslookup 192.168.12.238
Server: 192.168.12.7
Address 1: 192.168.12.7 dc1.hq.com
Name: 192.168.12.238
Address 1: 192.168.12.238 serialnumbergoeshere.hq.com
在另一台计算机上
> nslookup 192.168.12.238
Server: 127.0.1.1
Address: 127.0.1.1#53
238.12.168.192.in-addr.arpa name = serialnumbergoeshere.hq.com.
2017年1月10日更新
我找到了答案。您必须在hostname命令后重新启动网络服务。
systemctl restart systemd-networkd.service
答案 0 :(得分:0)
您必须在hostname命令之后重新启动网络服务。
systemctl restart systemd-networkd.service
– schustercp
答案 1 :(得分:0)
我正在寻找类似的功能。
我的第一个想法是将/ etc / hostname符号链接到另一个分区上的文件,并确保在出现以下引导消息之前systemd[1]: Set hostname to <myhostname>
挂载该分区。
但是,在更深入地挖掘之后,事情就变得不那么简单了。从我在其他地方找到的:
我希望initramfs将您的/ etc / hostname与实际的主机名打包在一起,也许您需要重新生成initramfs?
systemd在initramfs中启动,它从initramfs设置主机名,但是在将root切换到实际系统后,它会重新执行并再次设置主机名,因此无论如何您都应该以正确的主机名结束
因此,我最终得到了Daniel Schepler提供的解决方案。 这是系统服务:
[Unit]
Description=Update hostname to what we want
Before=systemd-networkd.target
After=mountdata.service
RequiresMountsFor=/usr
DefaultDependencies=no
[Service]
Type=simple
ExecStart=/usr/bin/mycustomhostnamescript.sh
[Install]
WantedBy=multi-user.target
脚本:
...
hostn=$(cat "$FILE_SERIAL")
echo "setting hostname=$hostn"
echo "$hostn" > /etc/hostname
hostname "$hostn"
...
请不要在脚本中使用hostnamectl,这一点很重要,因为它的依赖项尚未加载,它将失败!
该解决方案无需启动网络服务即可工作,因为它尚未启动。它也仅需重启一次即可。