]> git.proxmox.com Git - mirror_zfs-debian.git/blob - etc/init.d/zfs-import.in
fea661bbc53e756b47a7d2b987b2e20c885309a3
[mirror_zfs-debian.git] / etc / init.d / zfs-import.in
1 #!@SHELL@
2 #
3 # zfs-import This script will import ZFS pools
4 #
5 # chkconfig: 2345 01 99
6 # description: This script will perform a verbatim import of ZFS pools
7 # during system boot.
8 # probe: true
9 #
10 ### BEGIN INIT INFO
11 # Provides: zfs-import
12 # Required-Start: mtab
13 # Required-Stop: $local_fs mtab
14 # Default-Start: S
15 # Default-Stop: 0 1 6
16 # X-Start-Before: checkfs
17 # X-Stop-After: zfs-mount
18 # Short-Description: Import ZFS pools
19 # Description: Run the `zpool import` command.
20 ### END INIT INFO
21 #
22 # NOTE: Not having '$local_fs' on Required-Start but only on Required-Stop
23 # is on purpose. If we have '$local_fs' in both (and X-Start-Before=checkfs)
24 # we get conflicts - import needs to be started extremely early,
25 # but not stopped too late.
26 #
27 # Released under the 2-clause BSD license.
28 #
29 # The original script that acted as a template for this script came from
30 # the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
31 # licensing stansa) in the commit dated Mar 24, 2011:
32 # https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
33
34 # Source the common init script
35 . @sysconfdir@/zfs/zfs-functions
36
37 # ----------------------------------------------------
38
39 do_depend()
40 {
41 after sysfs udev
42 keyword -lxc -openvz -prefix -vserver
43 }
44
45 # Use the zpool cache file to import pools
46 do_verbatim_import()
47 {
48 if [ -f "$ZPOOL_CACHE" ]
49 then
50 zfs_action "Importing ZFS pool(s)" \
51 "$ZPOOL" import -c "$ZPOOL_CACHE" -N -a
52 fi
53 }
54
55 # Support function to get a list of all pools, separated with ';'
56 find_pools()
57 {
58 local CMD="$*"
59 local pools
60
61 pools=$($CMD 2> /dev/null | \
62 grep -E "pool:|^[a-zA-Z0-9]" | \
63 sed 's@.*: @@' | \
64 sort | \
65 while read pool; do \
66 echo -n "$pool;"
67 done)
68
69 echo "${pools%%;}" # Return without the last ';'.
70 }
71
72 # Find and import all visible pools, even exported ones
73 do_import_all_visible()
74 {
75 local already_imported available_pools pool npools
76 local exception dir ZPOOL_IMPORT_PATH RET=0 r=1
77
78 # In case not shutdown cleanly.
79 [ -n "$init" ] && rm -f /etc/dfs/sharetab
80
81 # Just simplify code later on.
82 if [ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ]
83 then
84 # It's something, but not 'yes' so it's no good to us.
85 unset USE_DISK_BY_ID
86 fi
87
88 # Find list of already imported pools.
89 already_imported=$(find_pools "$ZPOOL" list -H -oname)
90 available_pools=$(find_pools "$ZPOOL" import)
91
92 # Just in case - seen it happen (that a pool isn't visable/found
93 # with a simple "zpool import" but only when using the "-d"
94 # option or setting ZPOOL_IMPORT_PATH).
95 if [ -d "/dev/disk/by-id" ]
96 then
97 npools=$(find_pools "$ZPOOL" import -d /dev/disk/by-id)
98 if [ -n "$npools" ]
99 then
100 # Because we have found extra pool(s) here, which wasn't
101 # found 'normally', we need to force USE_DISK_BY_ID to
102 # make sure we're able to actually import it/them later.
103 USE_DISK_BY_ID='yes'
104
105 if [ -n "$available_pools" ]
106 then
107 # Filter out duplicates (pools found with the simpl
108 # "zpool import" but which is also found with the
109 # "zpool import -d ...").
110 npools=$(echo "$npools" | sed "s,$available_pools,,")
111
112 # Add the list to the existing list of
113 # available pools
114 available_pools="$available_pools;$npools"
115 else
116 available_pools="$npools"
117 fi
118 fi
119 fi
120
121 # Filter out any exceptions...
122 if [ -n "$ZFS_POOL_EXCEPTIONS" ]
123 then
124 local found=""
125 local apools=""
126 OLD_IFS="$IFS" ; IFS=";"
127
128 for pool in $available_pools
129 do
130 for exception in $ZFS_POOL_EXCEPTIONS
131 do
132 [ "$pool" = "$exception" ] && continue 2
133 found="$pool"
134 done
135
136 if [ -n "$found" ]
137 then
138 if [ -n "$apools" ]
139 then
140 apools="$apools;$pool"
141 else
142 apools="$pool"
143 fi
144 fi
145 done
146
147 IFS="$OLD_IFS"
148 available_pools="$apools"
149 fi
150
151 # For backwards compatibility, make sure that ZPOOL_IMPORT_PATH is set
152 # to something we can use later with the real import(s). We want to
153 # make sure we find all by* dirs, BUT by-vdev should be first (if it
154 # exists).
155 if [ -n "$USE_DISK_BY_ID" -a -z "$ZPOOL_IMPORT_PATH" ]
156 then
157 local dirs
158 dirs="$(for dir in $(echo /dev/disk/by-*)
159 do
160 # Ignore by-vdev here - we want it first!
161 echo "$dir" | grep -q /by-vdev && continue
162 [ ! -d "$dir" ] && continue
163
164 echo -n "$dir:"
165 done | sed 's,:$,,g')"
166
167 if [ -d "/dev/disk/by-vdev" ]
168 then
169 # Add by-vdev at the beginning.
170 ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:"
171 fi
172
173 # Help with getting LUKS partitions etc imported.
174 if [ -d "/dev/mapper" ]; then
175 if [ -n "$ZPOOL_IMPORT_PATH" ]; then
176 ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH:/dev/mapper:"
177 else
178 ZPOOL_IMPORT_PATH="/dev/mapper:"
179 fi
180 fi
181
182 # ... and /dev at the very end, just for good measure.
183 ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH$dirs:/dev"
184 fi
185
186 # Needs to be exported for "zpool" to catch it.
187 [ -n "$ZPOOL_IMPORT_PATH" ] && export ZPOOL_IMPORT_PATH
188
189 # Mount all availible pools (except those set in ZFS_POOL_EXCEPTIONS.
190 #
191 # If not interactive (run from init - variable init='/sbin/init')
192 # we get ONE line for all pools being imported, with just a dot
193 # as status for each pool.
194 # Example: Importing ZFS pool(s)... [OK]
195 #
196 # If it IS interactive (started from the shell manually), then we
197 # get one line per pool importing.
198 # Example: Importing ZFS pool pool1 [OK]
199 # Importing ZFS pool pool2 [OK]
200 # [etc]
201 [ -n "$init" ] && zfs_log_begin_msg "Importing ZFS pool(s)"
202 OLD_IFS="$IFS" ; IFS=";"
203 for pool in $available_pools
204 do
205 [ -z "$pool" ] && continue
206
207 # We have pools that haven't been imported - import them
208 if [ -n "$init" ]
209 then
210 # Not interactive - a dot for each pool.
211 # Except on Gentoo where this doesn't work.
212 zfs_log_progress_msg "."
213 else
214 # Interactive - one 'Importing ...' line per pool
215 zfs_log_begin_msg "Importing ZFS pool $pool"
216 fi
217
218 # Import by using ZPOOL_IMPORT_PATH (either set above or in
219 # the config file) _or_ with the 'built in' default search
220 # paths. This is the preferred way.
221 "$ZPOOL" import -N ${ZPOOL_IMPORT_OPTS} "$pool" 2> /dev/null
222 r="$?" ; RET=$((RET + r))
223 if [ "$r" -eq 0 ]
224 then
225 # Output success and process the next pool
226 [ -z "$init" ] && zfs_log_end_msg 0
227 continue
228 fi
229 # We don't want a fail msg here, we're going to try import
230 # using the cache file soon and that might succeed.
231 [ ! -f "$ZPOOL_CACHE" ] && zfs_log_end_msg "$RET"
232
233 if [ "$r" -gt 0 -a -f "$ZPOOL_CACHE" ]
234 then
235 # Failed to import without a cache file. Try WITH...
236 if [ -z "$init" ] && check_boolean "$VERBOSE_MOUNT"
237 then
238 # Interactive + Verbose = more information
239 zfs_log_progress_msg " using cache file"
240 fi
241
242 "$ZPOOL" import -c "$ZPOOL_CACHE" -N ${ZPOOL_IMPORT_OPTS} \
243 "$pool" 2> /dev/null
244 r="$?" ; RET=$((RET + r))
245 if [ "$r" -eq 0 ]
246 then
247 [ -z "$init" ] && zfs_log_end_msg 0
248 continue 3 # Next pool
249 fi
250 zfs_log_end_msg "$RET"
251 fi
252 done
253 [ -n "$init" ] && zfs_log_end_msg "$RET"
254
255 IFS="$OLD_IFS"
256 [ -n "$already_imported" -a -z "$available_pools" ] && return 0
257
258 return "$RET"
259 }
260
261 do_import()
262 {
263 if check_boolean "$ZPOOL_IMPORT_ALL_VISIBLE"
264 then
265 do_import_all_visible
266 else
267 # This is the default option
268 do_verbatim_import
269 fi
270 }
271
272 # Output the status and list of pools
273 do_status()
274 {
275 check_module_loaded "zfs" || exit 0
276
277 "$ZPOOL" status && echo "" && "$ZPOOL" list
278 }
279
280 do_start()
281 {
282 if check_boolean "$VERBOSE_MOUNT"
283 then
284 zfs_log_begin_msg "Checking if ZFS userspace tools present"
285 fi
286
287 if checksystem
288 then
289 check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0
290
291 check_boolean "$VERBOSE_MOUNT" && \
292 zfs_log_begin_msg "Loading kernel ZFS infrastructure"
293
294 if ! load_module "zfs"
295 then
296 check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 1
297 return 5
298 fi
299 check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0
300
301 do_import && udev_trigger # just to make sure we get zvols.
302
303 return 0
304 else
305 return 1
306 fi
307 }
308
309 # ----------------------------------------------------
310
311 if [ ! -e /sbin/openrc-run ]
312 then
313 case "$1" in
314 start)
315 do_start
316 ;;
317 stop)
318 # no-op
319 ;;
320 status)
321 do_status
322 ;;
323 force-reload|condrestart|reload|restart)
324 # no-op
325 ;;
326 *)
327 [ -n "$1" ] && echo "Error: Unknown command $1."
328 echo "Usage: $0 {start|status}"
329 exit 3
330 ;;
331 esac
332
333 exit $?
334 else
335 # Create wrapper functions since Gentoo don't use the case part.
336 depend() { do_depend; }
337 start() { do_start; }
338 status() { do_status; }
339 fi