3 # zfs-import This script will import/export zfs pools.
5 # chkconfig: 2345 01 99
6 # description: This script will import/export zfs pools during system
8 # It is also responsible for all userspace zfs services.
12 # Provides: zfs-import
13 # Required-Start: zfs-zed
14 # Required-Stop: zfs-zed
17 # X-Start-Before: checkfs
18 # X-Stop-After: zfs-mount
19 # Short-Description: Import ZFS pools
20 # Description: Run the `zpool import` or `zpool export` commands.
23 # Released under the 2-clause BSD license.
25 # The original script that acted as a template for this script came from
26 # the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
27 # licensing stansa) in the commit dated Mar 24, 2011:
28 # https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
30 # Source the common init script
31 . @sysconfdir@/zfs/zfs-functions
33 # ----------------------------------------------------
37 after sysfs udev zfs-zed
38 keyword -lxc -openvz -prefix -vserver
41 # Support function to get a list of all pools, separated with ';'
47 pools=$($CMD 2> /dev/null | \
48 grep -E "pool:|^[a-zA-Z0-9]" | \
55 echo "${pools%%;}" # Return without the last ';'.
61 local already_imported available_pools pool npools
62 local exception dir ZPOOL_IMPORT_PATH RET=0 r=1
64 # In case not shutdown cleanly.
65 [ -n "$init" ] && rm -f /etc/dfs/sharetab
67 # Just simplify code later on.
68 if [ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ]
70 # It's something, but not 'yes' so it's no good to us.
74 # Find list of already imported pools.
75 already_imported=$(find_pools "$ZPOOL" list -H -oname)
76 available_pools=$(find_pools "$ZPOOL" import)
78 # Just in case - seen it happen (that a pool isn't visable/found
79 # with a simple "zpool import" but only when using the "-d"
80 # option or setting ZPOOL_IMPORT_PATH).
81 if [ -d "/dev/disk/by-id" ]
83 npools=$(find_pools "$ZPOOL" import -d /dev/disk/by-id)
86 # Because we have found extra pool(s) here, which wasn't
87 # found 'normaly', we need to force USE_DISK_BY_ID to
88 # make sure we're able to actually import it/them later.
91 if [ -n "$available_pools" ]
93 # Filter out duplicates (pools found with the simpl
94 # "zpool import" but which is also found with the
95 # "zpool import -d ...").
96 npools=$(echo "$npools" | sed "s,$available_pools,,")
98 # Add the list to the existing list of
100 available_pools="$available_pools;$npools"
102 available_pools="$npools"
107 # Filter out any exceptions...
108 if [ -n "$ZFS_POOL_EXCEPTIONS" ]
112 OLD_IFS="$IFS" ; IFS=";"
114 for pool in $available_pools
116 for exception in $ZFS_POOL_EXCEPTIONS
118 [ "$pool" = "$exception" ] && continue 2
126 apools="$apools;$pool"
134 available_pools="$apools"
137 # For backwards compability, make sure that ZPOOL_IMPORT_PATH is set
138 # to something we can use later with the real import(s). We want to
139 # make sure we find all by* dirs, BUT by-vdev should be first (if it
141 if [ -n "$USE_DISK_BY_ID" -a -z "$ZPOOL_IMPORT_PATH" ]
144 dirs="$(for dir in $(echo /dev/disk/by-*)
146 # Ignore by-vdev here - we wan't it first!
147 echo "$dir" | grep -q /by-vdev && continue
148 [ ! -d "$dir" ] && continue
151 done | sed 's,:$,,g')"
153 if [ -d "/dev/disk/by-vdev" ]
155 # Add by-vdev at the beginning.
156 ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:"
159 # Help with getting LUKS partitions etc imported.
160 if [ -d "/dev/mapper" ]; then
161 if [ -n "$ZPOOL_IMPORT_PATH" ]; then
162 ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH:/dev/mapper:"
164 ZPOOL_IMPORT_PATH="/dev/mapper:"
168 # ... and /dev at the very end, just for good measure.
169 ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH$dirs:/dev"
172 # Needs to be exported for "zpool" to catch it.
173 [ -n "$ZPOOL_IMPORT_PATH" ] && export ZPOOL_IMPORT_PATH
175 # Mount all availible pools (except those set in ZFS_POOL_EXCEPTIONS.
177 # If not interactive (run from init - variable init='/sbin/init')
178 # we get ONE line for all pools being imported, with just a dot
179 # as status for each pool.
180 # Example: Importing ZFS pool(s)... [OK]
182 # If it IS interactive (started from the shell manually), then we
183 # get one line per pool importing.
184 # Example: Importing ZFS pool pool1 [OK]
185 # Importing ZFS pool pool2 [OK]
187 [ -n "$init" ] && zfs_log_begin_msg "Importing ZFS pool(s)"
188 OLD_IFS="$IFS" ; IFS=";"
189 for pool in $available_pools
191 [ -z "$pool" ] && continue
193 # We have pools that haven't been imported - import them
196 # Not interactive - a dot for each pool.
197 # Except on Gentoo where this doesn't work.
198 zfs_log_progress_msg "."
200 # Interactive - one 'Importing ...' line per pool
201 zfs_log_begin_msg "Importing ZFS pool $pool"
204 # Import by using ZPOOL_IMPORT_PATH (either set above or in
205 # the config file) _or_ with the 'built in' default search
206 # paths. This is the prefered way.
207 "$ZPOOL" import -N "$pool" 2> /dev/null
208 r="$?" ; RET=$((RET + r))
211 # Output success and process the next pool
212 [ -z "$init" ] && zfs_log_end_msg 0
215 # We don't want a fail msg here, we're going to try import
216 # using the cache file soon and that might succeed.
217 [ ! -f "$ZPOOL_CACHE" ] && zfs_log_end_msg "$RET"
219 if [ "$r" -gt 0 -a -f "$ZPOOL_CACHE" ]
221 # Failed to import without a cache file. Try WITH...
222 if [ -z "$init" -a "$VERBOSE_MOUNT" = 'yes' ]
224 # Interactive + Verbose = more information
225 zfs_log_progress_msg " using cache file"
228 "$ZPOOL" import -c "$ZPOOL_CACHE" -N "$pool" 2> /dev/null
229 r="$?" ; RET=$((RET + r))
232 [ -z "$init" ] && zfs_log_end_msg 0
233 continue 3 # Next pool
235 zfs_log_end_msg "$RET"
238 [ -n "$init" ] && zfs_log_end_msg "$RET"
241 [ -n "$already_imported" -a -z "$available_pools" ] && return 0
249 local pool root_pool RET r
252 root_pool=$(get_root_pool)
254 [ -n "$init" ] && zfs_log_begin_msg "Exporting ZFS pool(s)"
255 TMPFILE=$(mktemp --tmpdir=/var/tmp zpool.XXXXX)
256 "$ZPOOL" list -H -oname > "$TMPFILE"
258 [ "$pool" = "$root_pool" ] && continue
262 # Interactive - one 'Importing ...' line per pool
263 zfs_log_begin_msg "Exporting ZFS pool $pool"
265 # Not interactive - a dot for each pool.
266 zfs_log_progress_msg "."
269 "$ZPOOL" export "$pool"
270 r="$?" ; RET=$((RET + r))
271 [ -z "$init" ] && zfs_log_end_msg "$r"
274 [ -n "$init" ] && zfs_log_end_msg "$RET"
277 # Output the status and list of pools
280 check_module_loaded "zfs" || exit 0
282 "$ZPOOL" status && echo "" && "$ZPOOL" list
287 if [ "$VERBOSE_MOUNT" = 'yes' ]
289 zfs_log_begin_msg "Checking if ZFS userspace tools present"
294 [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0
296 if [ "$VERBOSE_MOUNT" = 'yes' ]
298 zfs_log_begin_msg "Loading kernel ZFS infrastructure"
301 if ! load_module "zfs"
303 [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 1
306 [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0
308 do_import && udev_trigger # just to make sure we get zvols.
318 # Check to see if the module is even loaded.
319 check_module_loaded "zfs" || exit 0
324 # ----------------------------------------------------
326 if [ ! -e /etc/gentoo-release ]
338 force-reload|condrestart|reload|restart)
342 [ -n "$1" ] && echo "Error: Unknown command $1."
343 echo "Usage: $0 {start|stop|status}"
350 # Create wrapper functions since Gentoo don't use the case part.
351 depend() { do_depend; }
352 start() { do_start; }
354 status() { do_status; }