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 /*
14 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
15 * Copyright (c) 2013, 2018 by Delphix. All rights reserved.
16 * Copyright (c) 2016, 2017 Intel Corporation.
17 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
18 */
19
20 /*
21 * Functions to convert between a list of vdevs and an nvlist representing the
22 * configuration. Each entry in the list can be one of:
23 *
24 * Device vdevs
25 * disk=(path=..., devid=...)
26 * file=(path=...)
27 *
28 * Group vdevs
29 * raidz[1|2]=(...)
30 * mirror=(...)
31 *
32 * Hot spares
33 *
34 * While the underlying implementation supports it, group vdevs cannot contain
35 * other group vdevs. All userland verification of devices is contained within
36 * this file. If successful, the nvlist returned can be passed directly to the
37 * kernel; we've done as much verification as possible in userland.
38 *
39 * Hot spares are a special case, and passed down as an array of disk vdevs, at
40 * the same level as the root of the vdev tree.
41 *
42 * The only function exported by this file is 'make_root_vdev'. The
43 * function performs several passes:
44 *
45 * 1. Construct the vdev specification. Performs syntax validation and
46 * makes sure each device is valid.
47 * 2. Check for devices in use. Using libblkid to make sure that no
48 * devices are also in use. Some can be overridden using the 'force'
49 * flag, others cannot.
50 * 3. Check for replication errors if the 'force' flag is not specified.
51 * validates that the replication level is consistent across the
52 * entire pool.
53 * 4. Call libzfs to label any whole disks with an EFI label.
54 */
55
56 #include <assert.h>
57 #include <ctype.h>
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <libintl.h>
61 #include <libnvpair.h>
62 #include <libzutil.h>
63 #include <limits.h>
64 #include <sys/spa.h>
65 #include <stdio.h>
66 #include <string.h>
67 #include <unistd.h>
68 #include "zpool_util.h"
69 #include <sys/zfs_context.h>
70
71 #include <scsi/scsi.h>
72 #include <scsi/sg.h>
73 #include <sys/efi_partition.h>
74 #include <sys/stat.h>
75 #include <sys/mntent.h>
76 #include <uuid/uuid.h>
77 #include <blkid/blkid.h>
78
79 typedef struct vdev_disk_db_entry
80 {
81 /* 24 byte name + 1 byte NULL terminator to make GCC happy */
82 char id[25];
83 int sector_size;
84 } vdev_disk_db_entry_t;
85
86 /*
87 * Database of block devices that lie about physical sector sizes. The
88 * identification string must be precisely 24 characters to avoid false
89 * negatives
90 */
91 static vdev_disk_db_entry_t vdev_disk_database[] = {
92 {"ATA ADATA SSD S396 3", 8192},
93 {"ATA APPLE SSD SM128E", 8192},
94 {"ATA APPLE SSD SM256E", 8192},
95 {"ATA APPLE SSD SM512E", 8192},
96 {"ATA APPLE SSD SM768E", 8192},
97 {"ATA C400-MTFDDAC064M", 8192},
98 {"ATA C400-MTFDDAC128M", 8192},
99 {"ATA C400-MTFDDAC256M", 8192},
100 {"ATA C400-MTFDDAC512M", 8192},
101 {"ATA Corsair Force 3 ", 8192},
102 {"ATA Corsair Force GS", 8192},
103 {"ATA INTEL SSDSA2CT04", 8192},
104 {"ATA INTEL SSDSA2BZ10", 8192},
105 {"ATA INTEL SSDSA2BZ20", 8192},
106 {"ATA INTEL SSDSA2BZ30", 8192},
107 {"ATA INTEL SSDSA2CW04", 8192},
108 {"ATA INTEL SSDSA2CW08", 8192},
109 {"ATA INTEL SSDSA2CW12", 8192},
110 {"ATA INTEL SSDSA2CW16", 8192},
111 {"ATA INTEL SSDSA2CW30", 8192},
112 {"ATA INTEL SSDSA2CW60", 8192},
113 {"ATA INTEL SSDSC2CT06", 8192},
114 {"ATA INTEL SSDSC2CT12", 8192},
115 {"ATA INTEL SSDSC2CT18", 8192},
116 {"ATA INTEL SSDSC2CT24", 8192},
117 {"ATA INTEL SSDSC2CW06", 8192},
118 {"ATA INTEL SSDSC2CW12", 8192},
119 {"ATA INTEL SSDSC2CW18", 8192},
120 {"ATA INTEL SSDSC2CW24", 8192},
121 {"ATA INTEL SSDSC2CW48", 8192},
122 {"ATA KINGSTON SH100S3", 8192},
123 {"ATA KINGSTON SH103S3", 8192},
124 {"ATA M4-CT064M4SSD2 ", 8192},
125 {"ATA M4-CT128M4SSD2 ", 8192},
126 {"ATA M4-CT256M4SSD2 ", 8192},
127 {"ATA M4-CT512M4SSD2 ", 8192},
128 {"ATA OCZ-AGILITY2 ", 8192},
129 {"ATA OCZ-AGILITY3 ", 8192},
130 {"ATA OCZ-VERTEX2 3.5 ", 8192},
131 {"ATA OCZ-VERTEX3 ", 8192},
132 {"ATA OCZ-VERTEX3 LT ", 8192},
133 {"ATA OCZ-VERTEX3 MI ", 8192},
134 {"ATA OCZ-VERTEX4 ", 8192},
135 {"ATA SAMSUNG MZ7WD120", 8192},
136 {"ATA SAMSUNG MZ7WD240", 8192},
137 {"ATA SAMSUNG MZ7WD480", 8192},
138 {"ATA SAMSUNG MZ7WD960", 8192},
139 {"ATA SAMSUNG SSD 830 ", 8192},
140 {"ATA Samsung SSD 840 ", 8192},
141 {"ATA SanDisk SSD U100", 8192},
142 {"ATA TOSHIBA THNSNH06", 8192},
143 {"ATA TOSHIBA THNSNH12", 8192},
144 {"ATA TOSHIBA THNSNH25", 8192},
145 {"ATA TOSHIBA THNSNH51", 8192},
146 {"ATA APPLE SSD TS064C", 4096},
147 {"ATA APPLE SSD TS128C", 4096},
148 {"ATA APPLE SSD TS256C", 4096},
149 {"ATA APPLE SSD TS512C", 4096},
150 {"ATA INTEL SSDSA2M040", 4096},
151 {"ATA INTEL SSDSA2M080", 4096},
152 {"ATA INTEL SSDSA2M160", 4096},
153 {"ATA INTEL SSDSC2MH12", 4096},
154 {"ATA INTEL SSDSC2MH25", 4096},
155 {"ATA OCZ CORE_SSD ", 4096},
156 {"ATA OCZ-VERTEX ", 4096},
157 {"ATA SAMSUNG MCCOE32G", 4096},
158 {"ATA SAMSUNG MCCOE64G", 4096},
159 {"ATA SAMSUNG SSD PM80", 4096},
160 /* Flash drives optimized for 4KB IOs on larger pages */
161 {"ATA INTEL SSDSC2BA10", 4096},
162 {"ATA INTEL SSDSC2BA20", 4096},
163 {"ATA INTEL SSDSC2BA40", 4096},
164 {"ATA INTEL SSDSC2BA80", 4096},
165 {"ATA INTEL SSDSC2BB08", 4096},
166 {"ATA INTEL SSDSC2BB12", 4096},
167 {"ATA INTEL SSDSC2BB16", 4096},
168 {"ATA INTEL SSDSC2BB24", 4096},
169 {"ATA INTEL SSDSC2BB30", 4096},
170 {"ATA INTEL SSDSC2BB40", 4096},
171 {"ATA INTEL SSDSC2BB48", 4096},
172 {"ATA INTEL SSDSC2BB60", 4096},
173 {"ATA INTEL SSDSC2BB80", 4096},
174 {"ATA INTEL SSDSC2BW24", 4096},
175 {"ATA INTEL SSDSC2BW48", 4096},
176 {"ATA INTEL SSDSC2BP24", 4096},
177 {"ATA INTEL SSDSC2BP48", 4096},
178 {"NA SmrtStorSDLKAE9W", 4096},
179 {"NVMe Amazon EC2 NVMe ", 4096},
180 /* Imported from Open Solaris */
181 {"ATA MARVELL SD88SA02", 4096},
182 /* Advanced format Hard drives */
183 {"ATA Hitachi HDS5C303", 4096},
184 {"ATA SAMSUNG HD204UI ", 4096},
185 {"ATA ST2000DL004 HD20", 4096},
186 {"ATA WDC WD10EARS-00M", 4096},
187 {"ATA WDC WD10EARS-00S", 4096},
188 {"ATA WDC WD10EARS-00Z", 4096},
189 {"ATA WDC WD15EARS-00M", 4096},
190 {"ATA WDC WD15EARS-00S", 4096},
191 {"ATA WDC WD15EARS-00Z", 4096},
192 {"ATA WDC WD20EARS-00M", 4096},
193 {"ATA WDC WD20EARS-00S", 4096},
194 {"ATA WDC WD20EARS-00Z", 4096},
195 {"ATA WDC WD1600BEVT-0", 4096},
196 {"ATA WDC WD2500BEVT-0", 4096},
197 {"ATA WDC WD3200BEVT-0", 4096},
198 {"ATA WDC WD5000BEVT-0", 4096},
199 };
200
201
202 #define INQ_REPLY_LEN 96
203 #define INQ_CMD_LEN 6
204
205 static const int vdev_disk_database_size =
206 sizeof (vdev_disk_database) / sizeof (vdev_disk_database[0]);
207
208 boolean_t
check_sector_size_database(char * path,int * sector_size)209 check_sector_size_database(char *path, int *sector_size)
210 {
211 unsigned char inq_buff[INQ_REPLY_LEN];
212 unsigned char sense_buffer[32];
213 unsigned char inq_cmd_blk[INQ_CMD_LEN] =
214 {INQUIRY, 0, 0, 0, INQ_REPLY_LEN, 0};
215 sg_io_hdr_t io_hdr;
216 int error;
217 int fd;
218 int i;
219
220 /* Prepare INQUIRY command */
221 memset(&io_hdr, 0, sizeof (sg_io_hdr_t));
222 io_hdr.interface_id = 'S';
223 io_hdr.cmd_len = sizeof (inq_cmd_blk);
224 io_hdr.mx_sb_len = sizeof (sense_buffer);
225 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
226 io_hdr.dxfer_len = INQ_REPLY_LEN;
227 io_hdr.dxferp = inq_buff;
228 io_hdr.cmdp = inq_cmd_blk;
229 io_hdr.sbp = sense_buffer;
230 io_hdr.timeout = 10; /* 10 milliseconds is ample time */
231
232 if ((fd = open(path, O_RDONLY|O_DIRECT)) < 0)
233 return (B_FALSE);
234
235 error = ioctl(fd, SG_IO, (unsigned long) &io_hdr);
236
237 (void) close(fd);
238
239 if (error < 0)
240 return (B_FALSE);
241
242 if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
243 return (B_FALSE);
244
245 for (i = 0; i < vdev_disk_database_size; i++) {
246 if (memcmp(inq_buff + 8, vdev_disk_database[i].id, 24))
247 continue;
248
249 *sector_size = vdev_disk_database[i].sector_size;
250 return (B_TRUE);
251 }
252
253 return (B_FALSE);
254 }
255
256 static int
check_slice(const char * path,blkid_cache cache,int force,boolean_t isspare)257 check_slice(const char *path, blkid_cache cache, int force, boolean_t isspare)
258 {
259 int err;
260 char *value;
261
262 /* No valid type detected device is safe to use */
263 value = blkid_get_tag_value(cache, "TYPE", path);
264 if (value == NULL)
265 return (0);
266
267 /*
268 * If libblkid detects a ZFS device, we check the device
269 * using check_file() to see if it's safe. The one safe
270 * case is a spare device shared between multiple pools.
271 */
272 if (strcmp(value, "zfs_member") == 0) {
273 err = check_file(path, force, isspare);
274 } else {
275 if (force) {
276 err = 0;
277 } else {
278 err = -1;
279 vdev_error(gettext("%s contains a filesystem of "
280 "type '%s'\n"), path, value);
281 }
282 }
283
284 free(value);
285
286 return (err);
287 }
288
289 /*
290 * Validate that a disk including all partitions are safe to use.
291 *
292 * For EFI labeled disks this can done relatively easily with the libefi
293 * library. The partition numbers are extracted from the label and used
294 * to generate the expected /dev/ paths. Each partition can then be
295 * checked for conflicts.
296 *
297 * For non-EFI labeled disks (MBR/EBR/etc) the same process is possible
298 * but due to the lack of a readily available libraries this scanning is
299 * not implemented. Instead only the device path as given is checked.
300 */
301 static int
check_disk(const char * path,blkid_cache cache,int force,boolean_t isspare,boolean_t iswholedisk)302 check_disk(const char *path, blkid_cache cache, int force,
303 boolean_t isspare, boolean_t iswholedisk)
304 {
305 struct dk_gpt *vtoc;
306 char slice_path[MAXPATHLEN];
307 int err = 0;
308 int fd, i;
309 int flags = O_RDONLY|O_DIRECT;
310
311 if (!iswholedisk)
312 return (check_slice(path, cache, force, isspare));
313
314 /* only spares can be shared, other devices require exclusive access */
315 if (!isspare)
316 flags |= O_EXCL;
317
318 if ((fd = open(path, flags)) < 0) {
319 char *value = blkid_get_tag_value(cache, "TYPE", path);
320 (void) fprintf(stderr, gettext("%s is in use and contains "
321 "a %s filesystem.\n"), path, value ? value : "unknown");
322 free(value);
323 return (-1);
324 }
325
326 /*
327 * Expected to fail for non-EFI labeled disks. Just check the device
328 * as given and do not attempt to detect and scan partitions.
329 */
330 err = efi_alloc_and_read(fd, &vtoc);
331 if (err) {
332 (void) close(fd);
333 return (check_slice(path, cache, force, isspare));
334 }
335
336 /*
337 * The primary efi partition label is damaged however the secondary
338 * label at the end of the device is intact. Rather than use this
339 * label we should play it safe and treat this as a non efi device.
340 */
341 if (vtoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) {
342 efi_free(vtoc);
343 (void) close(fd);
344
345 if (force) {
346 /* Partitions will now be created using the backup */
347 return (0);
348 } else {
349 vdev_error(gettext("%s contains a corrupt primary "
350 "EFI label.\n"), path);
351 return (-1);
352 }
353 }
354
355 for (i = 0; i < vtoc->efi_nparts; i++) {
356
357 if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED ||
358 uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_guid))
359 continue;
360
361 if (strncmp(path, UDISK_ROOT, strlen(UDISK_ROOT)) == 0)
362 (void) snprintf(slice_path, sizeof (slice_path),
363 "%s%s%d", path, "-part", i+1);
364 else
365 (void) snprintf(slice_path, sizeof (slice_path),
366 "%s%s%d", path, isdigit(path[strlen(path)-1]) ?
367 "p" : "", i+1);
368
369 err = check_slice(slice_path, cache, force, isspare);
370 if (err)
371 break;
372 }
373
374 efi_free(vtoc);
375 (void) close(fd);
376
377 return (err);
378 }
379
380 int
check_device(const char * path,boolean_t force,boolean_t isspare,boolean_t iswholedisk)381 check_device(const char *path, boolean_t force,
382 boolean_t isspare, boolean_t iswholedisk)
383 {
384 blkid_cache cache;
385 int error;
386
387 error = blkid_get_cache(&cache, NULL);
388 if (error != 0) {
389 (void) fprintf(stderr, gettext("unable to access the blkid "
390 "cache.\n"));
391 return (-1);
392 }
393
394 error = check_disk(path, cache, force, isspare, iswholedisk);
395 blkid_put_cache(cache);
396
397 return (error);
398 }
399
400 void
after_zpool_upgrade(zpool_handle_t * zhp)401 after_zpool_upgrade(zpool_handle_t *zhp)
402 {
403 (void) zhp;
404 }
405
406 int
check_file(const char * file,boolean_t force,boolean_t isspare)407 check_file(const char *file, boolean_t force, boolean_t isspare)
408 {
409 return (check_file_generic(file, force, isspare));
410 }
411
412 /*
413 * Read from a sysfs file and return an allocated string. Removes
414 * the newline from the end of the string if there is one.
415 *
416 * Returns a string on success (which must be freed), or NULL on error.
417 */
zpool_sysfs_gets(char * path)418 static char *zpool_sysfs_gets(char *path)
419 {
420 int fd;
421 struct stat statbuf;
422 char *buf = NULL;
423 ssize_t count = 0;
424 fd = open(path, O_RDONLY);
425 if (fd < 0)
426 return (NULL);
427
428 if (fstat(fd, &statbuf) != 0) {
429 close(fd);
430 return (NULL);
431 }
432
433 buf = calloc(statbuf.st_size + 1, sizeof (*buf));
434 if (buf == NULL) {
435 close(fd);
436 return (NULL);
437 }
438
439 /*
440 * Note, we can read less bytes than st_size, and that's ok. Sysfs
441 * files will report their size is 4k even if they only return a small
442 * string.
443 */
444 count = read(fd, buf, statbuf.st_size);
445 if (count < 0) {
446 /* Error doing read() or we overran the buffer */
447 close(fd);
448 free(buf);
449 return (NULL);
450 }
451
452 /* Remove trailing newline */
453 if (count > 0 && buf[count - 1] == '\n')
454 buf[count - 1] = 0;
455
456 close(fd);
457
458 return (buf);
459 }
460
461 /*
462 * Write a string to a sysfs file.
463 *
464 * Returns 0 on success, non-zero otherwise.
465 */
zpool_sysfs_puts(char * path,char * str)466 static int zpool_sysfs_puts(char *path, char *str)
467 {
468 FILE *file;
469
470 file = fopen(path, "w");
471 if (!file) {
472 return (-1);
473 }
474
475 if (fputs(str, file) < 0) {
476 fclose(file);
477 return (-2);
478 }
479 fclose(file);
480 return (0);
481 }
482
483 /* Given a vdev nvlist_t, rescan its enclosure sysfs path */
484 static void
rescan_vdev_config_dev_sysfs_path(nvlist_t * vdev_nv)485 rescan_vdev_config_dev_sysfs_path(nvlist_t *vdev_nv)
486 {
487 update_vdev_config_dev_sysfs_path(vdev_nv,
488 fnvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_PATH),
489 ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
490 }
491
492 /*
493 * Given a power string: "on", "off", "1", or "0", return 0 if it's an
494 * off value, 1 if it's an on value, and -1 if the value is unrecognized.
495 */
zpool_power_parse_value(char * str)496 static int zpool_power_parse_value(char *str)
497 {
498 if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
499 return (0);
500
501 if ((strcmp(str, "on") == 0) || (strcmp(str, "1") == 0))
502 return (1);
503
504 return (-1);
505 }
506
507 /*
508 * Given a vdev string return an allocated string containing the sysfs path to
509 * its power control file. Also do a check if the power control file really
510 * exists and has correct permissions.
511 *
512 * Example returned strings:
513 *
514 * /sys/class/enclosure/0:0:122:0/10/power_status
515 * /sys/bus/pci/slots/10/power
516 *
517 * Returns allocated string on success (which must be freed), NULL on failure.
518 */
519 static char *
zpool_power_sysfs_path(zpool_handle_t * zhp,char * vdev)520 zpool_power_sysfs_path(zpool_handle_t *zhp, char *vdev)
521 {
522 const char *enc_sysfs_dir = NULL;
523 char *path = NULL;
524 nvlist_t *vdev_nv = zpool_find_vdev(zhp, vdev, NULL, NULL, NULL);
525
526 if (vdev_nv == NULL) {
527 return (NULL);
528 }
529
530 /* Make sure we're getting the updated enclosure sysfs path */
531 rescan_vdev_config_dev_sysfs_path(vdev_nv);
532
533 if (nvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
534 &enc_sysfs_dir) != 0) {
535 return (NULL);
536 }
537
538 if (asprintf(&path, "%s/power_status", enc_sysfs_dir) == -1)
539 return (NULL);
540
541 if (access(path, W_OK) != 0) {
542 free(path);
543 path = NULL;
544 /* No HDD 'power_control' file, maybe it's NVMe? */
545 if (asprintf(&path, "%s/power", enc_sysfs_dir) == -1) {
546 return (NULL);
547 }
548
549 if (access(path, R_OK | W_OK) != 0) {
550 /* Not NVMe either */
551 free(path);
552 return (NULL);
553 }
554 }
555
556 return (path);
557 }
558
559 /*
560 * Given a path to a sysfs power control file, return B_TRUE if you should use
561 * "on/off" words to control it, or B_FALSE otherwise ("0/1" to control).
562 */
563 static boolean_t
zpool_power_use_word(char * sysfs_path)564 zpool_power_use_word(char *sysfs_path)
565 {
566 if (strcmp(&sysfs_path[strlen(sysfs_path) - strlen("power_status")],
567 "power_status") == 0) {
568 return (B_TRUE);
569 }
570 return (B_FALSE);
571 }
572
573 /*
574 * Check the sysfs power control value for a vdev.
575 *
576 * Returns:
577 * 0 - Power is off
578 * 1 - Power is on
579 * -1 - Error or unsupported
580 */
581 int
zpool_power_current_state(zpool_handle_t * zhp,char * vdev)582 zpool_power_current_state(zpool_handle_t *zhp, char *vdev)
583 {
584 char *val;
585 int rc;
586
587 char *path = zpool_power_sysfs_path(zhp, vdev);
588 if (path == NULL)
589 return (-1);
590
591 val = zpool_sysfs_gets(path);
592 if (val == NULL) {
593 free(path);
594 return (-1);
595 }
596
597 rc = zpool_power_parse_value(val);
598 free(val);
599 free(path);
600 return (rc);
601 }
602
603 /*
604 * Turn on or off the slot to a device
605 *
606 * Device path is the full path to the device (like /dev/sda or /dev/sda1).
607 *
608 * Return code:
609 * 0: Success
610 * ENOTSUP: Power control not supported for OS
611 * EBADSLT: Couldn't read current power state
612 * ENOENT: No sysfs path to power control
613 * EIO: Couldn't write sysfs power value
614 * EBADE: Sysfs power value didn't change
615 */
616 int
zpool_power(zpool_handle_t * zhp,char * vdev,boolean_t turn_on)617 zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on)
618 {
619 char *sysfs_path;
620 const char *val;
621 int rc;
622 int timeout_ms;
623
624 rc = zpool_power_current_state(zhp, vdev);
625 if (rc == -1) {
626 return (EBADSLT);
627 }
628
629 /* Already correct value? */
630 if (rc == (int)turn_on)
631 return (0);
632
633 sysfs_path = zpool_power_sysfs_path(zhp, vdev);
634 if (sysfs_path == NULL)
635 return (ENOENT);
636
637 if (zpool_power_use_word(sysfs_path)) {
638 val = turn_on ? "on" : "off";
639 } else {
640 val = turn_on ? "1" : "0";
641 }
642
643 rc = zpool_sysfs_puts(sysfs_path, (char *)val);
644
645 free(sysfs_path);
646 if (rc != 0) {
647 return (EIO);
648 }
649
650 /*
651 * Wait up to 30 seconds for sysfs power value to change after
652 * writing it.
653 */
654 timeout_ms = zpool_getenv_int("ZPOOL_POWER_ON_SLOT_TIMEOUT_MS", 30000);
655 for (int i = 0; i < MAX(1, timeout_ms / 200); i++) {
656 rc = zpool_power_current_state(zhp, vdev);
657 if (rc == (int)turn_on)
658 return (0); /* success */
659
660 fsleep(0.200); /* 200ms */
661 }
662
663 /* sysfs value never changed */
664 return (EBADE);
665 }
666