]>
Commit | Line | Data |
---|---|---|
5702dc92 DH |
1 | #!/bin/sh |
2 | ||
3 | # The hostname and hostid of the last system to access a ZFS pool are stored in | |
4 | # the ZFS pool itself. A pool is foreign if, during `zfs import`, the current | |
5 | # hostname and hostid are different than the stored values thereof. | |
6 | # | |
7 | # The hostname and hostid on Solaris are intrinsic, but they are not on Linux, | |
8 | # so the spl kernel module invokes /bin/hostname and /usr/bin/hostid from the | |
9 | # userland in its initialization routine. | |
10 | # | |
11 | # However, these two indentifiers are usually undefined in the Linux initramfs | |
12 | # environment, so the /etc/hostname and /etc/hostid files must be added to the | |
13 | # initrd. Things like a DHCP lease change can affect the hostid too. | |
14 | # | |
15 | # ZFS requires stable values for hostname and hostid, but basic Linux systems | |
16 | # do not. The hostid is therefore stabilized by creating the /etc/hostid file | |
17 | # in the regular environment if it does not already exist. An undefined | |
18 | # hostname is usuallly stable. | |
19 | # | |
20 | # Neither /etc/hostname nor /etc/hostid are controlled configuration files in | |
21 | # Debian distributions, but the spl package nevertheless installs a dummy | |
22 | # /etc/hostid file that contains the HW_INVALID_HOSTID sentinal value so that | |
23 | # the package manager will track it. | |
24 | ||
25 | # This result is always an eight-character hexadecimal number sans the 0x | |
26 | # prefix. Remember that /usr/bin/hostid generates a value if the /etc/hostid | |
27 | # file doesn't exist or is malformed. | |
28 | HOSTID=$(hostid) | |
29 | ||
30 | if [ -f /etc/hostid -a "0x$HOSTID" != "0xffffffff" ] | |
31 | then | |
32 | # This system already has a stable hostid. | |
33 | exit 0 | |
34 | fi | |
35 | ||
36 | # Truncate the dummy file and generate the actual system hostid. | |
37 | : >/etc/hostid | |
38 | HOSTID=$(hostid) | |
39 | ||
40 | # @TODO: Check whether this method is appropriate for gethostid(2) on big | |
41 | # endian systems. The /etc/hostname file on i386 and amd64 systems must be | |
42 | # a little endian integer of exacly four bytes. Regardless, a consistent | |
43 | # hostid is more important than a correct byte order here. | |
44 | ||
45 | # Conveniences like a ${HOSTID:$ii:2} substring range or a `sed` one-liner | |
46 | # are prohibited here because this file must be dash-compatible by policy. | |
47 | AA=$(echo $HOSTID | cut -b 1,2) | |
48 | BB=$(echo $HOSTID | cut -b 3,4) | |
49 | CC=$(echo $HOSTID | cut -b 5,6) | |
50 | DD=$(echo $HOSTID | cut -b 7,8) | |
51 | ||
52 | # Invoke the external printf because the dash builtin lacks the byte format. | |
53 | /usr/bin/printf "\x$DD\x$CC\x$BB\x$AA" >"/etc/hostid" | |
54 | ||
55 | # @ASSERT: [ "$HOSTID" = "$(hostid)" ] |