xref: /freebsd/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_import_os.c (revision 22649d4dba730d46244fd2dff4fd174903c8379f)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 /*
13  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
14  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
15  * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
16  * Copyright 2015 RackTop Systems.
17  * Copyright (c) 2016, Intel Corporation.
18  */
19 
20 /*
21  * Pool import support functions.
22  *
23  * Used by zpool, ztest, zdb, and zhack to locate importable configs. Since
24  * these commands are expected to run in the global zone, we can assume
25  * that the devices are all readable when called.
26  *
27  * To import a pool, we rely on reading the configuration information from the
28  * ZFS label of each device.  If we successfully read the label, then we
29  * organize the configuration information in the following hierarchy:
30  *
31  *	pool guid -> toplevel vdev guid -> label txg
32  *
33  * Duplicate entries matching this same tuple will be discarded.  Once we have
34  * examined every device, we pick the best label txg config for each toplevel
35  * vdev.  We then arrange these toplevel vdevs into a complete pool config, and
36  * update any paths that have changed.  Finally, we attempt to import the pool
37  * using our derived config, and record the results.
38  */
39 
40 #include <ctype.h>
41 #include <dirent.h>
42 #include <errno.h>
43 #include <libintl.h>
44 #include <libgen.h>
45 #include <stddef.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <sys/stat.h>
50 #include <unistd.h>
51 #include <fcntl.h>
52 #include <sys/dktp/fdisk.h>
53 #include <sys/vdev_impl.h>
54 #include <sys/fs/zfs.h>
55 
56 #include <libzutil.h>
57 #include <libnvpair.h>
58 #include <libzfs.h>
59 
60 #include "zutil_import.h"
61 
62 #ifdef HAVE_LIBUDEV
63 #include <libudev.h>
64 #include <sched.h>
65 #endif
66 #include <blkid/blkid.h>
67 
68 #define	DEV_BYID_PATH	"/dev/disk/by-id/"
69 
70 /*
71  * Skip devices with well known prefixes:
72  * there can be side effects when opening devices which need to be avoided.
73  *
74  * hpet        - High Precision Event Timer
75  * watchdog[N] - Watchdog must be closed in a special way.
76  */
77 static boolean_t
should_skip_dev(const char * dev)78 should_skip_dev(const char *dev)
79 {
80 	return ((strcmp(dev, "watchdog") == 0) ||
81 	    (strncmp(dev, "watchdog", 8) == 0 && isdigit(dev[8])) ||
82 	    (strcmp(dev, "hpet") == 0));
83 }
84 
85 /*
86  * Common predicate for zpool_dev_probe_ok() and its fd variant: only a
87  * block device, or a regular file large enough to hold a label, may be
88  * probed.  Anything else is refused.
89  */
90 static boolean_t
dev_stat_probe_ok(const struct stat64 * statbuf)91 dev_stat_probe_ok(const struct stat64 *statbuf)
92 {
93 	return (S_ISBLK(statbuf->st_mode) ||
94 	    (S_ISREG(statbuf->st_mode) && statbuf->st_size >= SPA_MINDEVSIZE));
95 }
96 
97 /*
98  * Determine if a path may be safely opened to probe for a vdev label.
99  * Only regular files large enough to hold a label and block devices are
100  * acceptable.  Anything else is refused: opening other device nodes can
101  * have side effects (e.g. arming a watchdog) and opening a FIFO blocks
102  * indefinitely.  stat64() never blocks, even on a FIFO.
103  */
104 boolean_t
zpool_dev_probe_ok(const char * path)105 zpool_dev_probe_ok(const char *path)
106 {
107 	struct stat64 statbuf;
108 
109 	if (should_skip_dev(zfs_basename(path)))
110 		return (B_FALSE);
111 
112 	/* Ignore failed stats. */
113 	if (stat64(path, &statbuf) != 0)
114 		return (B_FALSE);
115 
116 	return (dev_stat_probe_ok(&statbuf));
117 }
118 
119 /*
120  * As zpool_dev_probe_ok(), but re-check the type of an object already
121  * opened.  A path naming a symlink may have been repointed at a different
122  * node between the stat64() above and the open(), so only trust a
123  * descriptor which is still a block device or a large enough regular file.
124  */
125 boolean_t
zpool_dev_probe_ok_fd(int fd)126 zpool_dev_probe_ok_fd(int fd)
127 {
128 	struct stat64 statbuf;
129 
130 	if (fstat64(fd, &statbuf) != 0)
131 		return (B_FALSE);
132 
133 	return (dev_stat_probe_ok(&statbuf));
134 }
135 
136 int
zfs_dev_flush(int fd)137 zfs_dev_flush(int fd)
138 {
139 	return (ioctl(fd, BLKFLSBUF));
140 }
141 
142 void
zpool_open_func(void * arg)143 zpool_open_func(void *arg)
144 {
145 	rdsk_node_t *rn = arg;
146 	libpc_handle_t *hdl = rn->rn_hdl;
147 	nvlist_t *config;
148 	uint64_t vdev_guid = 0;
149 	int error;
150 	int num_labels = 0;
151 	int fd;
152 
153 	if (!zpool_dev_probe_ok(rn->rn_name))
154 		return;
155 
156 	/*
157 	 * Preferentially open using O_DIRECT to bypass the block device
158 	 * cache which may be stale for multipath devices.  An EINVAL errno
159 	 * indicates O_DIRECT is unsupported so fallback to just O_RDONLY.
160 	 */
161 	fd = open(rn->rn_name, O_RDONLY | O_DIRECT | O_CLOEXEC);
162 	if ((fd < 0) && (errno == EINVAL))
163 		fd = open(rn->rn_name, O_RDONLY | O_CLOEXEC);
164 	if ((fd < 0) && (errno == EACCES))
165 		hdl->lpc_open_access_error = B_TRUE;
166 	if (fd < 0)
167 		return;
168 
169 	error = zpool_read_label(fd, &config, &num_labels);
170 	if (error != 0) {
171 		(void) close(fd);
172 		return;
173 	}
174 
175 	if (num_labels == 0) {
176 		(void) close(fd);
177 		nvlist_free(config);
178 		return;
179 	}
180 
181 	/*
182 	 * Check that the vdev is for the expected guid.  Additional entries
183 	 * are speculatively added based on the paths stored in the labels.
184 	 * Entries with valid paths but incorrect guids must be removed.
185 	 */
186 	error = nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid);
187 	if (error || (rn->rn_vdev_guid && rn->rn_vdev_guid != vdev_guid)) {
188 		(void) close(fd);
189 		nvlist_free(config);
190 		return;
191 	}
192 
193 	(void) close(fd);
194 
195 	rn->rn_config = config;
196 	rn->rn_num_labels = num_labels;
197 
198 	/*
199 	 * Add additional entries for paths described by this label.
200 	 */
201 	if (rn->rn_labelpaths) {
202 		const char *path = NULL;
203 		const char *devid = NULL;
204 		rdsk_node_t *slice;
205 		avl_index_t where;
206 		int error;
207 
208 		if (label_paths(rn->rn_hdl, rn->rn_config, &path, &devid))
209 			return;
210 
211 		/*
212 		 * Allow devlinks to stabilize so all paths are available.
213 		 */
214 		zpool_disk_wait(rn->rn_name);
215 
216 		if (path != NULL) {
217 			slice = zutil_alloc(hdl, sizeof (rdsk_node_t));
218 			slice->rn_name = zutil_strdup(hdl, path);
219 			slice->rn_vdev_guid = vdev_guid;
220 			slice->rn_avl = rn->rn_avl;
221 			slice->rn_hdl = hdl;
222 			slice->rn_order = IMPORT_ORDER_PREFERRED_1;
223 			slice->rn_labelpaths = B_FALSE;
224 			pthread_mutex_lock(rn->rn_lock);
225 			if (avl_find(rn->rn_avl, slice, &where)) {
226 			pthread_mutex_unlock(rn->rn_lock);
227 				free(slice->rn_name);
228 				free(slice);
229 			} else {
230 				avl_insert(rn->rn_avl, slice, where);
231 				pthread_mutex_unlock(rn->rn_lock);
232 				zpool_open_func(slice);
233 			}
234 		}
235 
236 		if (devid != NULL) {
237 			slice = zutil_alloc(hdl, sizeof (rdsk_node_t));
238 			error = asprintf(&slice->rn_name, "%s%s",
239 			    DEV_BYID_PATH, devid);
240 			if (error == -1) {
241 				free(slice);
242 				return;
243 			}
244 
245 			slice->rn_vdev_guid = vdev_guid;
246 			slice->rn_avl = rn->rn_avl;
247 			slice->rn_hdl = hdl;
248 			slice->rn_order = IMPORT_ORDER_PREFERRED_2;
249 			slice->rn_labelpaths = B_FALSE;
250 			pthread_mutex_lock(rn->rn_lock);
251 			if (avl_find(rn->rn_avl, slice, &where)) {
252 				pthread_mutex_unlock(rn->rn_lock);
253 				free(slice->rn_name);
254 				free(slice);
255 			} else {
256 				avl_insert(rn->rn_avl, slice, where);
257 				pthread_mutex_unlock(rn->rn_lock);
258 				zpool_open_func(slice);
259 			}
260 		}
261 	}
262 }
263 
264 static const char * const
265 zpool_default_import_path[] = {
266 	"/dev/disk/by-vdev",	/* Custom rules, use first if they exist */
267 	"/dev/mapper",		/* Use multipath devices before components */
268 	"/dev/disk/by-partlabel", /* Single unique entry set by user */
269 	"/dev/disk/by-partuuid", /* Generated partition uuid */
270 	"/dev/disk/by-label",	/* Custom persistent labels */
271 	"/dev/disk/by-uuid",	/* Single unique entry and persistent */
272 	"/dev/disk/by-id",	/* May be multiple entries and persistent */
273 	"/dev/disk/by-path",	/* Encodes physical location and persistent */
274 	"/dev"			/* UNSAFE device names will change */
275 };
276 
277 const char * const *
zpool_default_search_paths(size_t * count)278 zpool_default_search_paths(size_t *count)
279 {
280 	*count = ARRAY_SIZE(zpool_default_import_path);
281 	return (zpool_default_import_path);
282 }
283 
284 /*
285  * Given a full path to a device determine if that device appears in the
286  * import search path.  If it does return the first match and store the
287  * index in the passed 'order' variable, otherwise return an error.
288  */
289 static int
zfs_path_order(const char * name,int * order)290 zfs_path_order(const char *name, int *order)
291 {
292 	const char *env = getenv("ZPOOL_IMPORT_PATH");
293 
294 	if (env) {
295 		for (int i = 0; ; ++i) {
296 			env += strspn(env, ":");
297 			size_t dirlen = strcspn(env, ":");
298 			if (dirlen) {
299 				if (strncmp(name, env, dirlen) == 0) {
300 					*order = i;
301 					return (0);
302 				}
303 
304 				env += dirlen;
305 			} else
306 				break;
307 		}
308 	} else {
309 		for (int i = 0; i < ARRAY_SIZE(zpool_default_import_path);
310 		    ++i) {
311 			if (strncmp(name, zpool_default_import_path[i],
312 			    strlen(zpool_default_import_path[i])) == 0) {
313 				*order = i;
314 				return (0);
315 			}
316 		}
317 	}
318 
319 	return (ENOENT);
320 }
321 
322 /*
323  * Use libblkid to quickly enumerate all known zfs devices.
324  */
325 int
zpool_find_import_blkid(libpc_handle_t * hdl,pthread_mutex_t * lock,avl_tree_t ** slice_cache)326 zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
327     avl_tree_t **slice_cache)
328 {
329 	rdsk_node_t *slice;
330 	blkid_cache cache;
331 	blkid_dev_iterate iter;
332 	blkid_dev dev;
333 	avl_index_t where;
334 	int error;
335 
336 	*slice_cache = NULL;
337 
338 	error = blkid_get_cache(&cache, NULL);
339 	if (error != 0)
340 		return (error);
341 
342 	error = blkid_probe_all_new(cache);
343 	if (error != 0) {
344 		blkid_put_cache(cache);
345 		return (error);
346 	}
347 
348 	iter = blkid_dev_iterate_begin(cache);
349 	if (iter == NULL) {
350 		blkid_put_cache(cache);
351 		return (EINVAL);
352 	}
353 
354 	/* Only const char *s since 2.32 */
355 	error = blkid_dev_set_search(iter,
356 	    (char *)"TYPE", (char *)"zfs_member");
357 	if (error != 0) {
358 		blkid_dev_iterate_end(iter);
359 		blkid_put_cache(cache);
360 		return (error);
361 	}
362 
363 	*slice_cache = zutil_alloc(hdl, sizeof (avl_tree_t));
364 	avl_create(*slice_cache, slice_cache_compare, sizeof (rdsk_node_t),
365 	    offsetof(rdsk_node_t, rn_node));
366 
367 	while (blkid_dev_next(iter, &dev) == 0) {
368 		slice = zutil_alloc(hdl, sizeof (rdsk_node_t));
369 		slice->rn_name = zutil_strdup(hdl, blkid_dev_devname(dev));
370 		slice->rn_vdev_guid = 0;
371 		slice->rn_lock = lock;
372 		slice->rn_avl = *slice_cache;
373 		slice->rn_hdl = hdl;
374 		slice->rn_labelpaths = B_TRUE;
375 
376 		error = zfs_path_order(slice->rn_name, &slice->rn_order);
377 		if (error == 0)
378 			slice->rn_order += IMPORT_ORDER_SCAN_OFFSET;
379 		else
380 			slice->rn_order = IMPORT_ORDER_DEFAULT;
381 
382 		pthread_mutex_lock(lock);
383 		if (avl_find(*slice_cache, slice, &where)) {
384 			free(slice->rn_name);
385 			free(slice);
386 		} else {
387 			avl_insert(*slice_cache, slice, where);
388 		}
389 		pthread_mutex_unlock(lock);
390 	}
391 
392 	blkid_dev_iterate_end(iter);
393 	blkid_put_cache(cache);
394 
395 	return (0);
396 }
397 
398 /*
399  * Linux persistent device strings for vdev labels
400  *
401  * based on libudev for consistency with libudev disk add/remove events
402  */
403 
404 typedef struct vdev_dev_strs {
405 	char	vds_devid[128];
406 	char	vds_devphys[128];
407 } vdev_dev_strs_t;
408 
409 #ifdef HAVE_LIBUDEV
410 
411 /*
412  * Obtain the persistent device id string (describes what)
413  *
414  * used by ZED vdev matching for auto-{online,expand,replace}
415  */
416 int
zfs_device_get_devid(struct udev_device * dev,char * bufptr,size_t buflen)417 zfs_device_get_devid(struct udev_device *dev, char *bufptr, size_t buflen)
418 {
419 	struct udev_list_entry *entry;
420 	const char *bus;
421 	char devbyid[MAXPATHLEN];
422 
423 	/* The bus based by-id path is preferred */
424 	bus = udev_device_get_property_value(dev, "ID_BUS");
425 
426 	if (bus == NULL) {
427 		const char *dm_uuid;
428 
429 		/*
430 		 * For multipath nodes use the persistent uuid based identifier
431 		 *
432 		 * Example: /dev/disk/by-id/dm-uuid-mpath-35000c5006304de3f
433 		 */
434 		dm_uuid = udev_device_get_property_value(dev, "DM_UUID");
435 		if (dm_uuid != NULL) {
436 			(void) snprintf(bufptr, buflen, "dm-uuid-%s", dm_uuid);
437 			return (0);
438 		}
439 
440 		/*
441 		 * For volumes use the persistent /dev/zvol/dataset identifier
442 		 */
443 		entry = udev_device_get_devlinks_list_entry(dev);
444 		while (entry != NULL) {
445 			const char *name;
446 
447 			name = udev_list_entry_get_name(entry);
448 			if (strncmp(name, ZVOL_ROOT, strlen(ZVOL_ROOT)) == 0) {
449 				(void) strlcpy(bufptr, name, buflen);
450 				return (0);
451 			}
452 			entry = udev_list_entry_get_next(entry);
453 		}
454 
455 		/*
456 		 * NVME 'by-id' symlinks are similar to bus case
457 		 */
458 		struct udev_device *parent;
459 
460 		parent = udev_device_get_parent_with_subsystem_devtype(dev,
461 		    "nvme", NULL);
462 		if (parent != NULL)
463 			bus = "nvme";	/* continue with bus symlink search */
464 		else
465 			return (ENODATA);
466 	}
467 
468 	/*
469 	 * locate the bus specific by-id link
470 	 */
471 	(void) snprintf(devbyid, sizeof (devbyid), "%s%s-", DEV_BYID_PATH, bus);
472 	entry = udev_device_get_devlinks_list_entry(dev);
473 	while (entry != NULL) {
474 		const char *name;
475 
476 		name = udev_list_entry_get_name(entry);
477 		if (strncmp(name, devbyid, strlen(devbyid)) == 0) {
478 			name += strlen(DEV_BYID_PATH);
479 			(void) strlcpy(bufptr, name, buflen);
480 			return (0);
481 		}
482 		entry = udev_list_entry_get_next(entry);
483 	}
484 
485 	return (ENODATA);
486 }
487 
488 /*
489  * Obtain the persistent physical location string (describes where)
490  *
491  * used by ZED vdev matching for auto-{online,expand,replace}
492  */
493 int
zfs_device_get_physical(struct udev_device * dev,char * bufptr,size_t buflen)494 zfs_device_get_physical(struct udev_device *dev, char *bufptr, size_t buflen)
495 {
496 	const char *physpath = NULL;
497 	struct udev_list_entry *entry;
498 
499 	/*
500 	 * Normal disks use ID_PATH for their physical path.
501 	 */
502 	physpath = udev_device_get_property_value(dev, "ID_PATH");
503 	if (physpath != NULL && strlen(physpath) > 0) {
504 		(void) strlcpy(bufptr, physpath, buflen);
505 		return (0);
506 	}
507 
508 	/*
509 	 * Device mapper devices are virtual and don't have a physical
510 	 * path. For them we use ID_VDEV instead, which is setup via the
511 	 * /etc/vdev_id.conf file.  ID_VDEV provides a persistent path
512 	 * to a virtual device.  If you don't have vdev_id.conf setup,
513 	 * you cannot use multipath autoreplace with device mapper.
514 	 */
515 	physpath = udev_device_get_property_value(dev, "ID_VDEV");
516 	if (physpath != NULL && strlen(physpath) > 0) {
517 		(void) strlcpy(bufptr, physpath, buflen);
518 		return (0);
519 	}
520 
521 	/*
522 	 * For ZFS volumes use the persistent /dev/zvol/dataset identifier
523 	 */
524 	entry = udev_device_get_devlinks_list_entry(dev);
525 	while (entry != NULL) {
526 		physpath = udev_list_entry_get_name(entry);
527 		if (strncmp(physpath, ZVOL_ROOT, strlen(ZVOL_ROOT)) == 0) {
528 			(void) strlcpy(bufptr, physpath, buflen);
529 			return (0);
530 		}
531 		entry = udev_list_entry_get_next(entry);
532 	}
533 
534 	/*
535 	 * For all other devices fallback to using the by-uuid name.
536 	 */
537 	entry = udev_device_get_devlinks_list_entry(dev);
538 	while (entry != NULL) {
539 		physpath = udev_list_entry_get_name(entry);
540 		if (strncmp(physpath, "/dev/disk/by-uuid", 17) == 0) {
541 			(void) strlcpy(bufptr, physpath, buflen);
542 			return (0);
543 		}
544 		entry = udev_list_entry_get_next(entry);
545 	}
546 
547 	return (ENODATA);
548 }
549 
550 /*
551  * A disk is considered a multipath whole disk when:
552  *	DEVNAME key value has "dm-"
553  *	DM_NAME key value has "mpath" prefix
554  *	DM_UUID key exists
555  *	ID_PART_TABLE_TYPE key does not exist or is not gpt
556  */
557 static boolean_t
udev_mpath_whole_disk(struct udev_device * dev)558 udev_mpath_whole_disk(struct udev_device *dev)
559 {
560 	const char *devname, *type, *uuid;
561 
562 	devname = udev_device_get_property_value(dev, "DEVNAME");
563 	type = udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE");
564 	uuid = udev_device_get_property_value(dev, "DM_UUID");
565 
566 	if ((devname != NULL && strncmp(devname, "/dev/dm-", 8) == 0) &&
567 	    ((type == NULL) || (strcmp(type, "gpt") != 0)) &&
568 	    (uuid != NULL)) {
569 		return (B_TRUE);
570 	}
571 
572 	return (B_FALSE);
573 }
574 
575 static int
udev_device_is_ready(struct udev_device * dev)576 udev_device_is_ready(struct udev_device *dev)
577 {
578 #ifdef HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED
579 	return (udev_device_get_is_initialized(dev));
580 #else
581 	/* wait for DEVLINKS property to be initialized */
582 	return (udev_device_get_property_value(dev, "DEVLINKS") != NULL);
583 #endif
584 }
585 
586 #else
587 
588 int
zfs_device_get_devid(struct udev_device * dev,char * bufptr,size_t buflen)589 zfs_device_get_devid(struct udev_device *dev, char *bufptr, size_t buflen)
590 {
591 	(void) dev, (void) bufptr, (void) buflen;
592 	return (ENODATA);
593 }
594 
595 int
zfs_device_get_physical(struct udev_device * dev,char * bufptr,size_t buflen)596 zfs_device_get_physical(struct udev_device *dev, char *bufptr, size_t buflen)
597 {
598 	(void) dev, (void) bufptr, (void) buflen;
599 	return (ENODATA);
600 }
601 
602 #endif /* HAVE_LIBUDEV */
603 
604 /*
605  * Wait up to timeout_ms for udev to set up the device node.  The device is
606  * considered ready when libudev determines it has been initialized, all of
607  * the device links have been verified to exist, and it has been allowed to
608  * settle.  At this point the device can be accessed reliably. Depending on
609  * the complexity of the udev rules this process could take several seconds.
610  */
611 int
zpool_label_disk_wait(const char * path,int timeout_ms)612 zpool_label_disk_wait(const char *path, int timeout_ms)
613 {
614 #ifdef HAVE_LIBUDEV
615 	struct udev *udev;
616 	struct udev_device *dev = NULL;
617 	char nodepath[MAXPATHLEN];
618 	char *sysname = NULL;
619 	int ret = ENODEV;
620 	int settle_ms = 50;
621 	long sleep_ms = 10;
622 	hrtime_t start, settle;
623 
624 	if ((udev = udev_new()) == NULL)
625 		return (ENXIO);
626 
627 	start = gethrtime();
628 	settle = 0;
629 
630 	do {
631 		if (sysname == NULL) {
632 			if (realpath(path, nodepath) != NULL) {
633 				sysname = strrchr(nodepath, '/') + 1;
634 			} else {
635 				(void) usleep(sleep_ms * MILLISEC);
636 				continue;
637 			}
638 		}
639 
640 		dev = udev_device_new_from_subsystem_sysname(udev,
641 		    "block", sysname);
642 		if ((dev != NULL) && udev_device_is_ready(dev)) {
643 			struct udev_list_entry *links, *link = NULL;
644 
645 			ret = 0;
646 			links = udev_device_get_devlinks_list_entry(dev);
647 
648 			udev_list_entry_foreach(link, links) {
649 				struct stat64 statbuf;
650 				const char *name;
651 
652 				name = udev_list_entry_get_name(link);
653 				errno = 0;
654 				if (stat64(name, &statbuf) == 0 && errno == 0)
655 					continue;
656 
657 				settle = 0;
658 				ret = ENODEV;
659 				break;
660 			}
661 
662 			if (ret == 0) {
663 				if (settle == 0) {
664 					settle = gethrtime();
665 				} else if (NSEC2MSEC(gethrtime() - settle) >=
666 				    settle_ms) {
667 					udev_device_unref(dev);
668 					break;
669 				}
670 			}
671 		}
672 
673 		udev_device_unref(dev);
674 		(void) usleep(sleep_ms * MILLISEC);
675 
676 	} while (NSEC2MSEC(gethrtime() - start) < timeout_ms);
677 
678 	udev_unref(udev);
679 
680 	return (ret);
681 #else
682 	int settle_ms = 50;
683 	long sleep_ms = 10;
684 	hrtime_t start, settle;
685 	struct stat64 statbuf;
686 
687 	start = gethrtime();
688 	settle = 0;
689 
690 	do {
691 		errno = 0;
692 		if ((stat64(path, &statbuf) == 0) && (errno == 0)) {
693 			if (settle == 0)
694 				settle = gethrtime();
695 			else if (NSEC2MSEC(gethrtime() - settle) >= settle_ms)
696 				return (0);
697 		} else if (errno != ENOENT) {
698 			return (errno);
699 		}
700 
701 		usleep(sleep_ms * MILLISEC);
702 	} while (NSEC2MSEC(gethrtime() - start) < timeout_ms);
703 
704 	return (ENODEV);
705 #endif /* HAVE_LIBUDEV */
706 }
707 
708 /*
709  * Simplified version of zpool_label_disk_wait() where we wait for a device
710  * to appear using the default timeouts.
711  */
712 int
zpool_disk_wait(const char * path)713 zpool_disk_wait(const char *path)
714 {
715 	int timeout;
716 	timeout = zpool_getenv_int("ZPOOL_IMPORT_UDEV_TIMEOUT_MS",
717 	    DISK_LABEL_WAIT);
718 
719 	return (zpool_label_disk_wait(path, timeout));
720 }
721 
722 /*
723  * Encode the persistent devices strings
724  * used for the vdev disk label
725  */
726 static int
encode_device_strings(const char * path,vdev_dev_strs_t * ds,boolean_t wholedisk)727 encode_device_strings(const char *path, vdev_dev_strs_t *ds,
728     boolean_t wholedisk)
729 {
730 #ifdef HAVE_LIBUDEV
731 	struct udev *udev;
732 	struct udev_device *dev = NULL;
733 	char nodepath[MAXPATHLEN];
734 	char *sysname;
735 	int ret = ENODEV;
736 	hrtime_t start;
737 
738 	if ((udev = udev_new()) == NULL)
739 		return (ENXIO);
740 
741 	/* resolve path to a runtime device node instance */
742 	if (realpath(path, nodepath) == NULL)
743 		goto no_dev;
744 
745 	sysname = strrchr(nodepath, '/') + 1;
746 
747 	/*
748 	 * Wait up to 3 seconds for udev to set up the device node context
749 	 */
750 	start = gethrtime();
751 	do {
752 		dev = udev_device_new_from_subsystem_sysname(udev, "block",
753 		    sysname);
754 		if (dev == NULL)
755 			goto no_dev;
756 		if (udev_device_is_ready(dev))
757 			break;  /* udev ready */
758 
759 		udev_device_unref(dev);
760 		dev = NULL;
761 
762 		if (NSEC2MSEC(gethrtime() - start) < 10)
763 			(void) sched_yield();	/* yield/busy wait up to 10ms */
764 		else
765 			(void) usleep(10 * MILLISEC);
766 
767 	} while (NSEC2MSEC(gethrtime() - start) < (3 * MILLISEC));
768 
769 	if (dev == NULL)
770 		goto no_dev;
771 
772 	/*
773 	 * Only whole disks require extra device strings
774 	 */
775 	if (!wholedisk && !udev_mpath_whole_disk(dev))
776 		goto no_dev;
777 
778 	ret = zfs_device_get_devid(dev, ds->vds_devid, sizeof (ds->vds_devid));
779 	if (ret != 0)
780 		goto no_dev_ref;
781 
782 	/* physical location string (optional) */
783 	if (zfs_device_get_physical(dev, ds->vds_devphys,
784 	    sizeof (ds->vds_devphys)) != 0) {
785 		ds->vds_devphys[0] = '\0'; /* empty string --> not available */
786 	}
787 
788 no_dev_ref:
789 	udev_device_unref(dev);
790 no_dev:
791 	udev_unref(udev);
792 
793 	return (ret);
794 #else
795 	(void) path;
796 	(void) ds;
797 	(void) wholedisk;
798 	return (ENOENT);
799 #endif
800 }
801 
802 /*
803  * Rescan the enclosure sysfs path for turning on enclosure LEDs and store it
804  * in the nvlist * (if applicable).  Like:
805  *    vdev_enc_sysfs_path: '/sys/class/enclosure/11:0:1:0/SLOT 4'
806  *
807  * If an old path was in the nvlist, and the rescan can not find a new path,
808  * then keep the old path, since the disk may have been removed.
809  *
810  * path: The vdev path (value from ZPOOL_CONFIG_PATH)
811  * key: The nvlist_t name (like ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH)
812  */
813 void
update_vdev_config_dev_sysfs_path(nvlist_t * nv,const char * path,const char * key)814 update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path,
815     const char *key)
816 {
817 	char *upath, *spath;
818 	const char *oldpath = NULL;
819 
820 	(void) nvlist_lookup_string(nv, key, &oldpath);
821 
822 	/* Add enclosure sysfs path (if disk is in an enclosure). */
823 	upath = zfs_get_underlying_path(path);
824 	spath = zfs_get_enclosure_sysfs_path(upath);
825 
826 	if (spath) {
827 		(void) nvlist_add_string(nv, key, spath);
828 	} else {
829 		/*
830 		 * We couldn't dynamically scan the disk's enclosure sysfs path.
831 		 * This could be because the disk went away.  If there's an old
832 		 * enclosure sysfs path in the nvlist, then keep using it.
833 		 */
834 		if (!oldpath) {
835 			(void) nvlist_remove_all(nv, key);
836 		}
837 	}
838 
839 	free(upath);
840 	free(spath);
841 }
842 
843 /*
844  * This will get called for each leaf vdev.
845  */
846 static int
sysfs_path_pool_vdev_iter_f(void * hdl_data,nvlist_t * nv,void * data)847 sysfs_path_pool_vdev_iter_f(void *hdl_data, nvlist_t *nv, void *data)
848 {
849 	(void) hdl_data, (void) data;
850 
851 	const char *path = NULL;
852 	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
853 		return (1);
854 
855 	/* Rescan our enclosure sysfs path for this vdev */
856 	update_vdev_config_dev_sysfs_path(nv, path,
857 	    ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
858 	return (0);
859 }
860 
861 /*
862  * Given an nvlist for our pool (with vdev tree), iterate over all the
863  * leaf vdevs and update their ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH.
864  */
865 void
update_vdevs_config_dev_sysfs_path(nvlist_t * config)866 update_vdevs_config_dev_sysfs_path(nvlist_t *config)
867 {
868 	nvlist_t *nvroot = NULL;
869 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
870 	    &nvroot) == 0);
871 	for_each_vdev_in_nvlist(nvroot, sysfs_path_pool_vdev_iter_f, NULL);
872 }
873 
874 /*
875  * Update a leaf vdev's persistent device strings
876  *
877  * - only applies for a dedicated leaf vdev (aka whole disk)
878  * - updated during pool create|add|attach|import
879  * - used for matching device matching during auto-{online,expand,replace}
880  * - stored in a leaf disk config label (i.e. alongside 'path' NVP)
881  * - these strings are currently not used in kernel (i.e. for vdev_disk_open)
882  *
883  * single device node example:
884  * 	devid:		'scsi-MG03SCA300_350000494a8cb3d67-part1'
885  * 	phys_path:	'pci-0000:04:00.0-sas-0x50000394a8cb3d67-lun-0'
886  *
887  * multipath device node example:
888  * 	devid:		'dm-uuid-mpath-35000c5006304de3f'
889  *
890  * We also store the enclosure sysfs path for turning on enclosure LEDs
891  * (if applicable):
892  *	vdev_enc_sysfs_path: '/sys/class/enclosure/11:0:1:0/SLOT 4'
893  */
894 void
update_vdev_config_dev_strs(nvlist_t * nv)895 update_vdev_config_dev_strs(nvlist_t *nv)
896 {
897 	vdev_dev_strs_t vds;
898 	const char *env, *type, *path;
899 	uint64_t wholedisk = 0;
900 
901 	/*
902 	 * For the benefit of legacy ZFS implementations, allow
903 	 * for opting out of devid strings in the vdev label.
904 	 *
905 	 * example use:
906 	 *	env ZFS_VDEV_DEVID_OPT_OUT=YES zpool import dozer
907 	 *
908 	 * explanation:
909 	 * Older OpenZFS implementations had issues when attempting to
910 	 * display pool config VDEV names if a "devid" NVP value is
911 	 * present in the pool's config.
912 	 *
913 	 * For example, a pool that originated on illumos platform would
914 	 * have a devid value in the config and "zpool status" would fail
915 	 * when listing the config.
916 	 *
917 	 * A pool can be stripped of any "devid" values on import or
918 	 * prevented from adding them on zpool create|add by setting
919 	 * ZFS_VDEV_DEVID_OPT_OUT.
920 	 */
921 	env = getenv("ZFS_VDEV_DEVID_OPT_OUT");
922 	if (env && (strtoul(env, NULL, 0) > 0 ||
923 	    !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2))) {
924 		(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);
925 		(void) nvlist_remove_all(nv, ZPOOL_CONFIG_PHYS_PATH);
926 		return;
927 	}
928 
929 	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0 ||
930 	    strcmp(type, VDEV_TYPE_DISK) != 0) {
931 		return;
932 	}
933 	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
934 		return;
935 	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
936 
937 	/*
938 	 * Update device string values in the config nvlist.
939 	 */
940 	if (encode_device_strings(path, &vds, (boolean_t)wholedisk) == 0) {
941 		(void) nvlist_add_string(nv, ZPOOL_CONFIG_DEVID, vds.vds_devid);
942 		if (vds.vds_devphys[0] != '\0') {
943 			(void) nvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
944 			    vds.vds_devphys);
945 		}
946 		update_vdev_config_dev_sysfs_path(nv, path,
947 		    ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
948 	} else {
949 		/* Clear out any stale entries. */
950 		(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);
951 		(void) nvlist_remove_all(nv, ZPOOL_CONFIG_PHYS_PATH);
952 		(void) nvlist_remove_all(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
953 	}
954 }
955