]>
Commit | Line | Data |
---|---|---|
a5288165 | 1 | #!/bin/sh -e |
5702dc92 DH |
2 | |
3 | # The hostname and hostid of the last system to access a ZFS pool are stored in | |
e12f472d DH |
4 | # the ZFS pool itself. A pool is foreign if, during `zpool import`, the |
5 | # current hostname and hostid are different than the stored values thereof. | |
5702dc92 DH |
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 | |
e12f472d DH |
41 | # endian systems. (Update: It isn't.) |
42 | # | |
43 | # The /etc/hostname file on i386 and amd64 systems must be a little endian | |
44 | # integer of exacly four bytes. Regardless, a consistent hostid is more | |
45 | # important than a correct byte order here. | |
5702dc92 DH |
46 | |
47 | # Conveniences like a ${HOSTID:$ii:2} substring range or a `sed` one-liner | |
48 | # are prohibited here because this file must be dash-compatible by policy. | |
49 | AA=$(echo $HOSTID | cut -b 1,2) | |
50 | BB=$(echo $HOSTID | cut -b 3,4) | |
51 | CC=$(echo $HOSTID | cut -b 5,6) | |
52 | DD=$(echo $HOSTID | cut -b 7,8) | |
53 | ||
54 | # Invoke the external printf because the dash builtin lacks the byte format. | |
90e54d12 | 55 | "$(which printf)" "\x$DD\x$CC\x$BB\x$AA" >"/etc/hostid" |
5702dc92 DH |
56 | |
57 | # @ASSERT: [ "$HOSTID" = "$(hostid)" ] | |
e12f472d | 58 | |
a3ccb21a | 59 | #DEBHELPER# |