]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libexec/rc/rc.d/hostid
hostid: Generate random UUID by default
[FreeBSD/FreeBSD.git] / libexec / rc / rc.d / hostid
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
4 # Copyright (c) 2015 Xin LI <delphij@FreeBSD.org>
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 # SUCH DAMAGE.
26 #
27 # $FreeBSD$
28 #
29
30 # PROVIDE: hostid
31 # REQUIRE: sysctl
32 # KEYWORD: nojail
33
34 . /etc/rc.subr
35
36 name="hostid"
37 desc="Generate a unique host ID"
38 start_cmd="hostid_start"
39 stop_cmd=":"
40 reset_cmd="hostid_reset"
41 extra_commands="reset"
42 rcvar="hostid_enable"
43
44 hostid_set()
45 {
46         uuid=$1
47         # Generate hostid based on hostuuid - take first four bytes from md5(uuid).
48         id=`echo -n $uuid | /sbin/md5`
49         id="0x${id%????????????????????????}"
50
51         # Set both kern.hostuuid and kern.hostid.
52         #
53         startmsg "Setting hostuuid: ${uuid}."
54         ${SYSCTL} kern.hostuuid="${uuid}" >/dev/null
55         startmsg "Setting hostid: ${id}."
56         ${SYSCTL} kern.hostid=${id} >/dev/null
57 }
58
59 valid_hostid()
60 {
61         uuid=$1
62
63         x="[0-9a-f]"
64         y=$x$x$x$x
65
66         # Check against a blacklist before
67         # accepting the UUID.
68         case "${uuid}" in
69         00000000-0000-0000-0000-000000000000)
70                 ;;
71         00020003-0004-0005-0006-000700080009)
72                 ;;
73         03000200-0400-0500-0006-000700080009)
74                 ;;
75         07090201-0103-0301-0807-060504030201)
76                 ;;
77         11111111-1111-1111-1111-111111111111)
78                 ;;
79         11111111-2222-3333-4444-555555555555)
80                 ;;
81         4c4c4544-0000-2010-8020-80c04f202020)
82                 ;;
83         58585858-5858-5858-5858-585858585858)
84                 ;;
85         890e2d14-cacd-45d1-ae66-bc80e8bfeb0f)
86                 ;;
87         8e275844-178f-44a8-aceb-a7d7e5178c63)
88                 ;;
89         dc698397-fa54-4cf2-82c8-b1b5307a6a7f)
90                 ;;
91         fefefefe-fefe-fefe-fefe-fefefefefefe)
92                 ;;
93         *-ffff-ffff-ffff-ffffffffffff)
94                 ;;
95         $y$y-$y-$y-$y-$y$y$y)
96                 return 0
97                 ;;
98         esac
99
100         return 1
101 }
102
103 hostid_hardware()
104 {
105         uuid=`kenv -q smbios.system.uuid`
106
107         if valid_hostid $uuid; then
108                 echo "${uuid}"
109         fi
110 }
111
112 hostid_generate()
113 {
114         # First look for UUID in hardware.
115         uuid=`hostid_hardware`
116         if [ -z "${uuid}" ]; then
117                 warn "hostid: unable to figure out a UUID from DMI data, generating a new one"
118                 sleep 2
119                 # If not found, fall back to software-generated UUID.
120                 uuid=`uuidgen ${hostid_uuidgen_flags}`
121         fi
122         hostid_set $uuid
123 }
124
125 hostid_reset()
126 {
127         hostid_generate
128         # Store newly generated UUID in ${hostid_file}.
129         echo $uuid > ${hostid_file}
130         if [ $? -ne 0 ]; then
131                 warn "could not store hostuuid in ${hostid_file}."
132         fi
133 }
134
135 hostid_start()
136 {
137         # If ${hostid_file} already exists, we take UUID from there.
138         if [ -r ${hostid_file} ]; then
139                 read saved_hostid < ${hostid_file}
140                 if valid_hostid ${saved_hostid}; then
141                         hostid_set `cat ${hostid_file}`
142                         exit 0
143                 fi
144         fi
145
146         # No hostid file, generate UUID.
147         hostid_generate
148 }
149
150 load_rc_config $name
151 run_rc_command "$1"