Print this page
1693 persistent 'comment' field for a zpool
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libzfs/common/libzfs_pool.c
+++ new/usr/src/lib/libzfs/common/libzfs_pool.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25 25 * Copyright (c) 2011 by Delphix. All rights reserved.
26 26 */
27 27
28 28 #include <ctype.h>
29 29 #include <errno.h>
30 30 #include <devid.h>
31 31 #include <fcntl.h>
32 32 #include <libintl.h>
33 33 #include <stdio.h>
34 34 #include <stdlib.h>
35 35 #include <strings.h>
36 36 #include <unistd.h>
37 37 #include <sys/efi_partition.h>
38 38 #include <sys/vtoc.h>
39 39 #include <sys/zfs_ioctl.h>
40 40 #include <dlfcn.h>
41 41
42 42 #include "zfs_namecheck.h"
43 43 #include "zfs_prop.h"
44 44 #include "libzfs_impl.h"
45 45 #include "zfs_comutil.h"
46 46
47 47 static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
48 48
49 49 #define DISK_ROOT "/dev/dsk"
50 50 #define RDISK_ROOT "/dev/rdsk"
51 51 #define BACKUP_SLICE "s2"
52 52
53 53 typedef struct prop_flags {
54 54 int create:1; /* Validate property on creation */
55 55 int import:1; /* Validate property on import */
56 56 } prop_flags_t;
57 57
58 58 /*
59 59 * ====================================================================
60 60 * zpool property functions
61 61 * ====================================================================
62 62 */
63 63
64 64 static int
65 65 zpool_get_all_props(zpool_handle_t *zhp)
66 66 {
67 67 zfs_cmd_t zc = { 0 };
68 68 libzfs_handle_t *hdl = zhp->zpool_hdl;
69 69
70 70 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
71 71
72 72 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
73 73 return (-1);
74 74
75 75 while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
76 76 if (errno == ENOMEM) {
77 77 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
78 78 zcmd_free_nvlists(&zc);
79 79 return (-1);
80 80 }
81 81 } else {
82 82 zcmd_free_nvlists(&zc);
83 83 return (-1);
84 84 }
85 85 }
86 86
87 87 if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
88 88 zcmd_free_nvlists(&zc);
89 89 return (-1);
90 90 }
91 91
92 92 zcmd_free_nvlists(&zc);
93 93
94 94 return (0);
95 95 }
96 96
97 97 static int
98 98 zpool_props_refresh(zpool_handle_t *zhp)
99 99 {
100 100 nvlist_t *old_props;
101 101
102 102 old_props = zhp->zpool_props;
103 103
104 104 if (zpool_get_all_props(zhp) != 0)
105 105 return (-1);
106 106
107 107 nvlist_free(old_props);
108 108 return (0);
109 109 }
110 110
111 111 static char *
112 112 zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
113 113 zprop_source_t *src)
114 114 {
115 115 nvlist_t *nv, *nvl;
116 116 uint64_t ival;
117 117 char *value;
118 118 zprop_source_t source;
119 119
120 120 nvl = zhp->zpool_props;
121 121 if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
122 122 verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
123 123 source = ival;
124 124 verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
125 125 } else {
126 126 source = ZPROP_SRC_DEFAULT;
127 127 if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
128 128 value = "-";
129 129 }
130 130
131 131 if (src)
132 132 *src = source;
133 133
134 134 return (value);
135 135 }
136 136
137 137 uint64_t
138 138 zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
139 139 {
140 140 nvlist_t *nv, *nvl;
141 141 uint64_t value;
142 142 zprop_source_t source;
143 143
144 144 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
145 145 /*
146 146 * zpool_get_all_props() has most likely failed because
147 147 * the pool is faulted, but if all we need is the top level
148 148 * vdev's guid then get it from the zhp config nvlist.
149 149 */
150 150 if ((prop == ZPOOL_PROP_GUID) &&
151 151 (nvlist_lookup_nvlist(zhp->zpool_config,
152 152 ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
153 153 (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
154 154 == 0)) {
155 155 return (value);
156 156 }
157 157 return (zpool_prop_default_numeric(prop));
158 158 }
159 159
160 160 nvl = zhp->zpool_props;
161 161 if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
162 162 verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
163 163 source = value;
164 164 verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
165 165 } else {
166 166 source = ZPROP_SRC_DEFAULT;
167 167 value = zpool_prop_default_numeric(prop);
168 168 }
169 169
170 170 if (src)
171 171 *src = source;
172 172
173 173 return (value);
174 174 }
175 175
176 176 /*
177 177 * Map VDEV STATE to printed strings.
178 178 */
179 179 char *
180 180 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
181 181 {
182 182 switch (state) {
183 183 case VDEV_STATE_CLOSED:
184 184 case VDEV_STATE_OFFLINE:
185 185 return (gettext("OFFLINE"));
186 186 case VDEV_STATE_REMOVED:
187 187 return (gettext("REMOVED"));
188 188 case VDEV_STATE_CANT_OPEN:
189 189 if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
190 190 return (gettext("FAULTED"));
191 191 else if (aux == VDEV_AUX_SPLIT_POOL)
192 192 return (gettext("SPLIT"));
193 193 else
194 194 return (gettext("UNAVAIL"));
195 195 case VDEV_STATE_FAULTED:
196 196 return (gettext("FAULTED"));
197 197 case VDEV_STATE_DEGRADED:
198 198 return (gettext("DEGRADED"));
199 199 case VDEV_STATE_HEALTHY:
200 200 return (gettext("ONLINE"));
201 201 }
202 202
203 203 return (gettext("UNKNOWN"));
204 204 }
205 205
206 206 /*
207 207 * Get a zpool property value for 'prop' and return the value in
208 208 * a pre-allocated buffer.
209 209 */
210 210 int
211 211 zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
212 212 zprop_source_t *srctype)
213 213 {
214 214 uint64_t intval;
215 215 const char *strval;
216 216 zprop_source_t src = ZPROP_SRC_NONE;
217 217 nvlist_t *nvroot;
218 218 vdev_stat_t *vs;
219 219 uint_t vsc;
220 220
221 221 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
222 222 switch (prop) {
223 223 case ZPOOL_PROP_NAME:
224 224 (void) strlcpy(buf, zpool_get_name(zhp), len);
225 225 break;
226 226
227 227 case ZPOOL_PROP_HEALTH:
|
↓ open down ↓ |
227 lines elided |
↑ open up ↑ |
228 228 (void) strlcpy(buf, "FAULTED", len);
229 229 break;
230 230
231 231 case ZPOOL_PROP_GUID:
232 232 intval = zpool_get_prop_int(zhp, prop, &src);
233 233 (void) snprintf(buf, len, "%llu", intval);
234 234 break;
235 235
236 236 case ZPOOL_PROP_ALTROOT:
237 237 case ZPOOL_PROP_CACHEFILE:
238 + case ZPOOL_PROP_COMMENT:
238 239 if (zhp->zpool_props != NULL ||
239 240 zpool_get_all_props(zhp) == 0) {
240 241 (void) strlcpy(buf,
241 242 zpool_get_prop_string(zhp, prop, &src),
242 243 len);
243 244 if (srctype != NULL)
244 245 *srctype = src;
245 246 return (0);
246 247 }
247 248 /* FALLTHROUGH */
248 249 default:
249 250 (void) strlcpy(buf, "-", len);
250 251 break;
251 252 }
252 253
253 254 if (srctype != NULL)
254 255 *srctype = src;
255 256 return (0);
256 257 }
257 258
258 259 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
259 260 prop != ZPOOL_PROP_NAME)
260 261 return (-1);
261 262
262 263 switch (zpool_prop_get_type(prop)) {
263 264 case PROP_TYPE_STRING:
264 265 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
265 266 len);
266 267 break;
267 268
268 269 case PROP_TYPE_NUMBER:
269 270 intval = zpool_get_prop_int(zhp, prop, &src);
270 271
271 272 switch (prop) {
272 273 case ZPOOL_PROP_SIZE:
273 274 case ZPOOL_PROP_ALLOCATED:
274 275 case ZPOOL_PROP_FREE:
275 276 (void) zfs_nicenum(intval, buf, len);
276 277 break;
277 278
278 279 case ZPOOL_PROP_CAPACITY:
279 280 (void) snprintf(buf, len, "%llu%%",
280 281 (u_longlong_t)intval);
281 282 break;
282 283
283 284 case ZPOOL_PROP_DEDUPRATIO:
284 285 (void) snprintf(buf, len, "%llu.%02llux",
285 286 (u_longlong_t)(intval / 100),
286 287 (u_longlong_t)(intval % 100));
287 288 break;
288 289
289 290 case ZPOOL_PROP_HEALTH:
290 291 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
291 292 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
292 293 verify(nvlist_lookup_uint64_array(nvroot,
293 294 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
294 295 == 0);
295 296
296 297 (void) strlcpy(buf, zpool_state_to_name(intval,
297 298 vs->vs_aux), len);
298 299 break;
299 300 default:
300 301 (void) snprintf(buf, len, "%llu", intval);
301 302 }
302 303 break;
303 304
304 305 case PROP_TYPE_INDEX:
305 306 intval = zpool_get_prop_int(zhp, prop, &src);
306 307 if (zpool_prop_index_to_string(prop, intval, &strval)
307 308 != 0)
308 309 return (-1);
309 310 (void) strlcpy(buf, strval, len);
310 311 break;
311 312
312 313 default:
313 314 abort();
314 315 }
315 316
316 317 if (srctype)
317 318 *srctype = src;
318 319
319 320 return (0);
320 321 }
321 322
322 323 /*
323 324 * Check if the bootfs name has the same pool name as it is set to.
324 325 * Assuming bootfs is a valid dataset name.
325 326 */
326 327 static boolean_t
327 328 bootfs_name_valid(const char *pool, char *bootfs)
328 329 {
329 330 int len = strlen(pool);
330 331
331 332 if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
332 333 return (B_FALSE);
333 334
334 335 if (strncmp(pool, bootfs, len) == 0 &&
335 336 (bootfs[len] == '/' || bootfs[len] == '\0'))
336 337 return (B_TRUE);
337 338
338 339 return (B_FALSE);
339 340 }
340 341
341 342 /*
342 343 * Inspect the configuration to determine if any of the devices contain
343 344 * an EFI label.
344 345 */
345 346 static boolean_t
346 347 pool_uses_efi(nvlist_t *config)
347 348 {
348 349 nvlist_t **child;
349 350 uint_t c, children;
350 351
351 352 if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
352 353 &child, &children) != 0)
353 354 return (read_efi_label(config, NULL) >= 0);
354 355
355 356 for (c = 0; c < children; c++) {
356 357 if (pool_uses_efi(child[c]))
357 358 return (B_TRUE);
358 359 }
359 360 return (B_FALSE);
360 361 }
361 362
362 363 static boolean_t
363 364 pool_is_bootable(zpool_handle_t *zhp)
364 365 {
365 366 char bootfs[ZPOOL_MAXNAMELEN];
366 367
367 368 return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
368 369 sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
369 370 sizeof (bootfs)) != 0);
370 371 }
371 372
372 373
373 374 /*
374 375 * Given an nvlist of zpool properties to be set, validate that they are
375 376 * correct, and parse any numeric properties (index, boolean, etc) if they are
376 377 * specified as strings.
|
↓ open down ↓ |
129 lines elided |
↑ open up ↑ |
377 378 */
378 379 static nvlist_t *
379 380 zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
380 381 nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
381 382 {
382 383 nvpair_t *elem;
383 384 nvlist_t *retprops;
384 385 zpool_prop_t prop;
385 386 char *strval;
386 387 uint64_t intval;
387 - char *slash;
388 + char *slash, *check;
388 389 struct stat64 statbuf;
389 390 zpool_handle_t *zhp;
390 391 nvlist_t *nvroot;
391 392
392 393 if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
393 394 (void) no_memory(hdl);
394 395 return (NULL);
395 396 }
396 397
397 398 elem = NULL;
398 399 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
399 400 const char *propname = nvpair_name(elem);
400 401
401 402 /*
402 403 * Make sure this property is valid and applies to this type.
403 404 */
404 405 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
405 406 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
406 407 "invalid property '%s'"), propname);
407 408 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
408 409 goto error;
409 410 }
410 411
411 412 if (zpool_prop_readonly(prop)) {
412 413 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
413 414 "is readonly"), propname);
414 415 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
415 416 goto error;
416 417 }
417 418
418 419 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
419 420 &strval, &intval, errbuf) != 0)
420 421 goto error;
421 422
422 423 /*
423 424 * Perform additional checking for specific properties.
424 425 */
425 426 switch (prop) {
426 427 case ZPOOL_PROP_VERSION:
427 428 if (intval < version || intval > SPA_VERSION) {
428 429 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
429 430 "property '%s' number %d is invalid."),
430 431 propname, intval);
431 432 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
432 433 goto error;
433 434 }
434 435 break;
435 436
436 437 case ZPOOL_PROP_BOOTFS:
437 438 if (flags.create || flags.import) {
438 439 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
439 440 "property '%s' cannot be set at creation "
440 441 "or import time"), propname);
441 442 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
442 443 goto error;
443 444 }
444 445
445 446 if (version < SPA_VERSION_BOOTFS) {
446 447 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
447 448 "pool must be upgraded to support "
448 449 "'%s' property"), propname);
449 450 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
450 451 goto error;
451 452 }
452 453
453 454 /*
454 455 * bootfs property value has to be a dataset name and
455 456 * the dataset has to be in the same pool as it sets to.
456 457 */
457 458 if (strval[0] != '\0' && !bootfs_name_valid(poolname,
458 459 strval)) {
459 460 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
460 461 "is an invalid name"), strval);
461 462 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
462 463 goto error;
463 464 }
464 465
465 466 if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
466 467 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
467 468 "could not open pool '%s'"), poolname);
468 469 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
469 470 goto error;
470 471 }
471 472 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
472 473 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
473 474
474 475 /*
475 476 * bootfs property cannot be set on a disk which has
476 477 * been EFI labeled.
477 478 */
478 479 if (pool_uses_efi(nvroot)) {
479 480 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
480 481 "property '%s' not supported on "
481 482 "EFI labeled devices"), propname);
482 483 (void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf);
483 484 zpool_close(zhp);
484 485 goto error;
485 486 }
486 487 zpool_close(zhp);
487 488 break;
488 489
489 490 case ZPOOL_PROP_ALTROOT:
490 491 if (!flags.create && !flags.import) {
491 492 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
492 493 "property '%s' can only be set during pool "
493 494 "creation or import"), propname);
494 495 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
495 496 goto error;
496 497 }
497 498
498 499 if (strval[0] != '/') {
499 500 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
500 501 "bad alternate root '%s'"), strval);
501 502 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
502 503 goto error;
503 504 }
504 505 break;
505 506
506 507 case ZPOOL_PROP_CACHEFILE:
507 508 if (strval[0] == '\0')
508 509 break;
509 510
510 511 if (strcmp(strval, "none") == 0)
511 512 break;
512 513
513 514 if (strval[0] != '/') {
514 515 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
515 516 "property '%s' must be empty, an "
516 517 "absolute path, or 'none'"), propname);
517 518 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
518 519 goto error;
519 520 }
520 521
521 522 slash = strrchr(strval, '/');
522 523
523 524 if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
524 525 strcmp(slash, "/..") == 0) {
525 526 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
526 527 "'%s' is not a valid file"), strval);
527 528 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
528 529 goto error;
529 530 }
530 531
531 532 *slash = '\0';
532 533
533 534 if (strval[0] != '\0' &&
534 535 (stat64(strval, &statbuf) != 0 ||
535 536 !S_ISDIR(statbuf.st_mode))) {
|
↓ open down ↓ |
138 lines elided |
↑ open up ↑ |
536 537 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
537 538 "'%s' is not a valid directory"),
538 539 strval);
539 540 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
540 541 goto error;
541 542 }
542 543
543 544 *slash = '/';
544 545 break;
545 546
547 + case ZPOOL_PROP_COMMENT:
548 + for (check = strval; *check != '\0'; check++) {
549 + if (!isprint(*check)) {
550 + zfs_error_aux(hdl,
551 + dgettext(TEXT_DOMAIN,
552 + "comment may only have printable "
553 + "characters"));
554 + (void) zfs_error(hdl, EZFS_BADPROP,
555 + errbuf);
556 + goto error;
557 + }
558 + }
559 + if (strlen(strval) > ZPROP_MAX_COMMENT) {
560 + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
561 + "comment must not exceed %d characters"),
562 + ZPROP_MAX_COMMENT);
563 + (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
564 + goto error;
565 + }
566 + break;
546 567 case ZPOOL_PROP_READONLY:
547 568 if (!flags.import) {
548 569 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
549 570 "property '%s' can only be set at "
550 571 "import time"), propname);
551 572 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
552 573 goto error;
553 574 }
554 575 break;
555 576 }
556 577 }
557 578
558 579 return (retprops);
559 580 error:
560 581 nvlist_free(retprops);
561 582 return (NULL);
562 583 }
563 584
564 585 /*
565 586 * Set zpool property : propname=propval.
566 587 */
567 588 int
568 589 zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
569 590 {
570 591 zfs_cmd_t zc = { 0 };
571 592 int ret = -1;
572 593 char errbuf[1024];
573 594 nvlist_t *nvl = NULL;
574 595 nvlist_t *realprops;
575 596 uint64_t version;
576 597 prop_flags_t flags = { 0 };
577 598
578 599 (void) snprintf(errbuf, sizeof (errbuf),
579 600 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
580 601 zhp->zpool_name);
581 602
582 603 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
583 604 return (no_memory(zhp->zpool_hdl));
584 605
585 606 if (nvlist_add_string(nvl, propname, propval) != 0) {
586 607 nvlist_free(nvl);
587 608 return (no_memory(zhp->zpool_hdl));
588 609 }
589 610
590 611 version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
591 612 if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
592 613 zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
593 614 nvlist_free(nvl);
594 615 return (-1);
595 616 }
596 617
597 618 nvlist_free(nvl);
598 619 nvl = realprops;
599 620
600 621 /*
601 622 * Execute the corresponding ioctl() to set this property.
602 623 */
603 624 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
604 625
605 626 if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
606 627 nvlist_free(nvl);
607 628 return (-1);
608 629 }
609 630
610 631 ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
611 632
612 633 zcmd_free_nvlists(&zc);
613 634 nvlist_free(nvl);
614 635
615 636 if (ret)
616 637 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
617 638 else
618 639 (void) zpool_props_refresh(zhp);
619 640
620 641 return (ret);
621 642 }
622 643
623 644 int
624 645 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
625 646 {
626 647 libzfs_handle_t *hdl = zhp->zpool_hdl;
627 648 zprop_list_t *entry;
628 649 char buf[ZFS_MAXPROPLEN];
629 650
630 651 if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
631 652 return (-1);
632 653
633 654 for (entry = *plp; entry != NULL; entry = entry->pl_next) {
634 655
635 656 if (entry->pl_fixed)
636 657 continue;
637 658
638 659 if (entry->pl_prop != ZPROP_INVAL &&
639 660 zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
640 661 NULL) == 0) {
641 662 if (strlen(buf) > entry->pl_width)
642 663 entry->pl_width = strlen(buf);
643 664 }
644 665 }
645 666
646 667 return (0);
647 668 }
648 669
649 670
650 671 /*
651 672 * Don't start the slice at the default block of 34; many storage
652 673 * devices will use a stripe width of 128k, so start there instead.
653 674 */
654 675 #define NEW_START_BLOCK 256
655 676
656 677 /*
657 678 * Validate the given pool name, optionally putting an extended error message in
658 679 * 'buf'.
659 680 */
660 681 boolean_t
661 682 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
662 683 {
663 684 namecheck_err_t why;
664 685 char what;
665 686 int ret;
666 687
667 688 ret = pool_namecheck(pool, &why, &what);
668 689
669 690 /*
670 691 * The rules for reserved pool names were extended at a later point.
671 692 * But we need to support users with existing pools that may now be
672 693 * invalid. So we only check for this expanded set of names during a
673 694 * create (or import), and only in userland.
674 695 */
675 696 if (ret == 0 && !isopen &&
676 697 (strncmp(pool, "mirror", 6) == 0 ||
677 698 strncmp(pool, "raidz", 5) == 0 ||
678 699 strncmp(pool, "spare", 5) == 0 ||
679 700 strcmp(pool, "log") == 0)) {
680 701 if (hdl != NULL)
681 702 zfs_error_aux(hdl,
682 703 dgettext(TEXT_DOMAIN, "name is reserved"));
683 704 return (B_FALSE);
684 705 }
685 706
686 707
687 708 if (ret != 0) {
688 709 if (hdl != NULL) {
689 710 switch (why) {
690 711 case NAME_ERR_TOOLONG:
691 712 zfs_error_aux(hdl,
692 713 dgettext(TEXT_DOMAIN, "name is too long"));
693 714 break;
694 715
695 716 case NAME_ERR_INVALCHAR:
696 717 zfs_error_aux(hdl,
697 718 dgettext(TEXT_DOMAIN, "invalid character "
698 719 "'%c' in pool name"), what);
699 720 break;
700 721
701 722 case NAME_ERR_NOLETTER:
702 723 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
703 724 "name must begin with a letter"));
704 725 break;
705 726
706 727 case NAME_ERR_RESERVED:
707 728 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
708 729 "name is reserved"));
709 730 break;
710 731
711 732 case NAME_ERR_DISKLIKE:
712 733 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
713 734 "pool name is reserved"));
714 735 break;
715 736
716 737 case NAME_ERR_LEADING_SLASH:
717 738 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
718 739 "leading slash in name"));
719 740 break;
720 741
721 742 case NAME_ERR_EMPTY_COMPONENT:
722 743 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
723 744 "empty component in name"));
724 745 break;
725 746
726 747 case NAME_ERR_TRAILING_SLASH:
727 748 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
728 749 "trailing slash in name"));
729 750 break;
730 751
731 752 case NAME_ERR_MULTIPLE_AT:
732 753 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
733 754 "multiple '@' delimiters in name"));
734 755 break;
735 756
736 757 }
737 758 }
738 759 return (B_FALSE);
739 760 }
740 761
741 762 return (B_TRUE);
742 763 }
743 764
744 765 /*
745 766 * Open a handle to the given pool, even if the pool is currently in the FAULTED
746 767 * state.
747 768 */
748 769 zpool_handle_t *
749 770 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
750 771 {
751 772 zpool_handle_t *zhp;
752 773 boolean_t missing;
753 774
754 775 /*
755 776 * Make sure the pool name is valid.
756 777 */
757 778 if (!zpool_name_valid(hdl, B_TRUE, pool)) {
758 779 (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
759 780 dgettext(TEXT_DOMAIN, "cannot open '%s'"),
760 781 pool);
761 782 return (NULL);
762 783 }
763 784
764 785 if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
765 786 return (NULL);
766 787
767 788 zhp->zpool_hdl = hdl;
768 789 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
769 790
770 791 if (zpool_refresh_stats(zhp, &missing) != 0) {
771 792 zpool_close(zhp);
772 793 return (NULL);
773 794 }
774 795
775 796 if (missing) {
776 797 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
777 798 (void) zfs_error_fmt(hdl, EZFS_NOENT,
778 799 dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
779 800 zpool_close(zhp);
780 801 return (NULL);
781 802 }
782 803
783 804 return (zhp);
784 805 }
785 806
786 807 /*
787 808 * Like the above, but silent on error. Used when iterating over pools (because
788 809 * the configuration cache may be out of date).
789 810 */
790 811 int
791 812 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
792 813 {
793 814 zpool_handle_t *zhp;
794 815 boolean_t missing;
795 816
796 817 if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
797 818 return (-1);
798 819
799 820 zhp->zpool_hdl = hdl;
800 821 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
801 822
802 823 if (zpool_refresh_stats(zhp, &missing) != 0) {
803 824 zpool_close(zhp);
804 825 return (-1);
805 826 }
806 827
807 828 if (missing) {
808 829 zpool_close(zhp);
809 830 *ret = NULL;
810 831 return (0);
811 832 }
812 833
813 834 *ret = zhp;
814 835 return (0);
815 836 }
816 837
817 838 /*
818 839 * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
819 840 * state.
820 841 */
821 842 zpool_handle_t *
822 843 zpool_open(libzfs_handle_t *hdl, const char *pool)
823 844 {
824 845 zpool_handle_t *zhp;
825 846
826 847 if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
827 848 return (NULL);
828 849
829 850 if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
830 851 (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
831 852 dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
832 853 zpool_close(zhp);
833 854 return (NULL);
834 855 }
835 856
836 857 return (zhp);
837 858 }
838 859
839 860 /*
840 861 * Close the handle. Simply frees the memory associated with the handle.
841 862 */
842 863 void
843 864 zpool_close(zpool_handle_t *zhp)
844 865 {
845 866 if (zhp->zpool_config)
846 867 nvlist_free(zhp->zpool_config);
847 868 if (zhp->zpool_old_config)
848 869 nvlist_free(zhp->zpool_old_config);
849 870 if (zhp->zpool_props)
850 871 nvlist_free(zhp->zpool_props);
851 872 free(zhp);
852 873 }
853 874
854 875 /*
855 876 * Return the name of the pool.
856 877 */
857 878 const char *
858 879 zpool_get_name(zpool_handle_t *zhp)
859 880 {
860 881 return (zhp->zpool_name);
861 882 }
862 883
863 884
864 885 /*
865 886 * Return the state of the pool (ACTIVE or UNAVAILABLE)
866 887 */
867 888 int
868 889 zpool_get_state(zpool_handle_t *zhp)
869 890 {
870 891 return (zhp->zpool_state);
871 892 }
872 893
873 894 /*
874 895 * Create the named pool, using the provided vdev list. It is assumed
875 896 * that the consumer has already validated the contents of the nvlist, so we
876 897 * don't have to worry about error semantics.
877 898 */
878 899 int
879 900 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
880 901 nvlist_t *props, nvlist_t *fsprops)
881 902 {
882 903 zfs_cmd_t zc = { 0 };
883 904 nvlist_t *zc_fsprops = NULL;
884 905 nvlist_t *zc_props = NULL;
885 906 char msg[1024];
886 907 char *altroot;
887 908 int ret = -1;
888 909
889 910 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
890 911 "cannot create '%s'"), pool);
891 912
892 913 if (!zpool_name_valid(hdl, B_FALSE, pool))
893 914 return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
894 915
895 916 if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
896 917 return (-1);
897 918
898 919 if (props) {
899 920 prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
900 921
901 922 if ((zc_props = zpool_valid_proplist(hdl, pool, props,
902 923 SPA_VERSION_1, flags, msg)) == NULL) {
903 924 goto create_failed;
904 925 }
905 926 }
906 927
907 928 if (fsprops) {
908 929 uint64_t zoned;
909 930 char *zonestr;
910 931
911 932 zoned = ((nvlist_lookup_string(fsprops,
912 933 zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
913 934 strcmp(zonestr, "on") == 0);
914 935
915 936 if ((zc_fsprops = zfs_valid_proplist(hdl,
916 937 ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
917 938 goto create_failed;
918 939 }
919 940 if (!zc_props &&
920 941 (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
921 942 goto create_failed;
922 943 }
923 944 if (nvlist_add_nvlist(zc_props,
924 945 ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
925 946 goto create_failed;
926 947 }
927 948 }
928 949
929 950 if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
930 951 goto create_failed;
931 952
932 953 (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
933 954
934 955 if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
935 956
936 957 zcmd_free_nvlists(&zc);
937 958 nvlist_free(zc_props);
938 959 nvlist_free(zc_fsprops);
939 960
940 961 switch (errno) {
941 962 case EBUSY:
942 963 /*
943 964 * This can happen if the user has specified the same
944 965 * device multiple times. We can't reliably detect this
945 966 * until we try to add it and see we already have a
946 967 * label.
947 968 */
948 969 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
949 970 "one or more vdevs refer to the same device"));
950 971 return (zfs_error(hdl, EZFS_BADDEV, msg));
951 972
952 973 case EOVERFLOW:
953 974 /*
954 975 * This occurs when one of the devices is below
955 976 * SPA_MINDEVSIZE. Unfortunately, we can't detect which
956 977 * device was the problem device since there's no
957 978 * reliable way to determine device size from userland.
958 979 */
959 980 {
960 981 char buf[64];
961 982
962 983 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
963 984
964 985 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
965 986 "one or more devices is less than the "
966 987 "minimum size (%s)"), buf);
967 988 }
968 989 return (zfs_error(hdl, EZFS_BADDEV, msg));
969 990
970 991 case ENOSPC:
971 992 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
972 993 "one or more devices is out of space"));
973 994 return (zfs_error(hdl, EZFS_BADDEV, msg));
974 995
975 996 case ENOTBLK:
976 997 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
977 998 "cache device must be a disk or disk slice"));
978 999 return (zfs_error(hdl, EZFS_BADDEV, msg));
979 1000
980 1001 default:
981 1002 return (zpool_standard_error(hdl, errno, msg));
982 1003 }
983 1004 }
984 1005
985 1006 /*
986 1007 * If this is an alternate root pool, then we automatically set the
987 1008 * mountpoint of the root dataset to be '/'.
988 1009 */
989 1010 if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT),
990 1011 &altroot) == 0) {
991 1012 zfs_handle_t *zhp;
992 1013
993 1014 verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL);
994 1015 verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
995 1016 "/") == 0);
996 1017
997 1018 zfs_close(zhp);
998 1019 }
999 1020
1000 1021 create_failed:
1001 1022 zcmd_free_nvlists(&zc);
1002 1023 nvlist_free(zc_props);
1003 1024 nvlist_free(zc_fsprops);
1004 1025 return (ret);
1005 1026 }
1006 1027
1007 1028 /*
1008 1029 * Destroy the given pool. It is up to the caller to ensure that there are no
1009 1030 * datasets left in the pool.
1010 1031 */
1011 1032 int
1012 1033 zpool_destroy(zpool_handle_t *zhp)
1013 1034 {
1014 1035 zfs_cmd_t zc = { 0 };
1015 1036 zfs_handle_t *zfp = NULL;
1016 1037 libzfs_handle_t *hdl = zhp->zpool_hdl;
1017 1038 char msg[1024];
1018 1039
1019 1040 if (zhp->zpool_state == POOL_STATE_ACTIVE &&
1020 1041 (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
1021 1042 return (-1);
1022 1043
1023 1044 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1024 1045
1025 1046 if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
1026 1047 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1027 1048 "cannot destroy '%s'"), zhp->zpool_name);
1028 1049
1029 1050 if (errno == EROFS) {
1030 1051 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1031 1052 "one or more devices is read only"));
1032 1053 (void) zfs_error(hdl, EZFS_BADDEV, msg);
1033 1054 } else {
1034 1055 (void) zpool_standard_error(hdl, errno, msg);
1035 1056 }
1036 1057
1037 1058 if (zfp)
1038 1059 zfs_close(zfp);
1039 1060 return (-1);
1040 1061 }
1041 1062
1042 1063 if (zfp) {
1043 1064 remove_mountpoint(zfp);
1044 1065 zfs_close(zfp);
1045 1066 }
1046 1067
1047 1068 return (0);
1048 1069 }
1049 1070
1050 1071 /*
1051 1072 * Add the given vdevs to the pool. The caller must have already performed the
1052 1073 * necessary verification to ensure that the vdev specification is well-formed.
1053 1074 */
1054 1075 int
1055 1076 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
1056 1077 {
1057 1078 zfs_cmd_t zc = { 0 };
1058 1079 int ret;
1059 1080 libzfs_handle_t *hdl = zhp->zpool_hdl;
1060 1081 char msg[1024];
1061 1082 nvlist_t **spares, **l2cache;
1062 1083 uint_t nspares, nl2cache;
1063 1084
1064 1085 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1065 1086 "cannot add to '%s'"), zhp->zpool_name);
1066 1087
1067 1088 if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1068 1089 SPA_VERSION_SPARES &&
1069 1090 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
1070 1091 &spares, &nspares) == 0) {
1071 1092 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1072 1093 "upgraded to add hot spares"));
1073 1094 return (zfs_error(hdl, EZFS_BADVERSION, msg));
1074 1095 }
1075 1096
1076 1097 if (pool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
1077 1098 ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
1078 1099 uint64_t s;
1079 1100
1080 1101 for (s = 0; s < nspares; s++) {
1081 1102 char *path;
1082 1103
1083 1104 if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
1084 1105 &path) == 0 && pool_uses_efi(spares[s])) {
1085 1106 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1086 1107 "device '%s' contains an EFI label and "
1087 1108 "cannot be used on root pools."),
1088 1109 zpool_vdev_name(hdl, NULL, spares[s],
1089 1110 B_FALSE));
1090 1111 return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
1091 1112 }
1092 1113 }
1093 1114 }
1094 1115
1095 1116 if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1096 1117 SPA_VERSION_L2CACHE &&
1097 1118 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
1098 1119 &l2cache, &nl2cache) == 0) {
1099 1120 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1100 1121 "upgraded to add cache devices"));
1101 1122 return (zfs_error(hdl, EZFS_BADVERSION, msg));
1102 1123 }
1103 1124
1104 1125 if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
1105 1126 return (-1);
1106 1127 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1107 1128
1108 1129 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
1109 1130 switch (errno) {
1110 1131 case EBUSY:
1111 1132 /*
1112 1133 * This can happen if the user has specified the same
1113 1134 * device multiple times. We can't reliably detect this
1114 1135 * until we try to add it and see we already have a
1115 1136 * label.
1116 1137 */
1117 1138 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1118 1139 "one or more vdevs refer to the same device"));
1119 1140 (void) zfs_error(hdl, EZFS_BADDEV, msg);
1120 1141 break;
1121 1142
1122 1143 case EOVERFLOW:
1123 1144 /*
1124 1145 * This occurrs when one of the devices is below
1125 1146 * SPA_MINDEVSIZE. Unfortunately, we can't detect which
1126 1147 * device was the problem device since there's no
1127 1148 * reliable way to determine device size from userland.
1128 1149 */
1129 1150 {
1130 1151 char buf[64];
1131 1152
1132 1153 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
1133 1154
1134 1155 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1135 1156 "device is less than the minimum "
1136 1157 "size (%s)"), buf);
1137 1158 }
1138 1159 (void) zfs_error(hdl, EZFS_BADDEV, msg);
1139 1160 break;
1140 1161
1141 1162 case ENOTSUP:
1142 1163 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1143 1164 "pool must be upgraded to add these vdevs"));
1144 1165 (void) zfs_error(hdl, EZFS_BADVERSION, msg);
1145 1166 break;
1146 1167
1147 1168 case EDOM:
1148 1169 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1149 1170 "root pool can not have multiple vdevs"
1150 1171 " or separate logs"));
1151 1172 (void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg);
1152 1173 break;
1153 1174
1154 1175 case ENOTBLK:
1155 1176 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1156 1177 "cache device must be a disk or disk slice"));
1157 1178 (void) zfs_error(hdl, EZFS_BADDEV, msg);
1158 1179 break;
1159 1180
1160 1181 default:
1161 1182 (void) zpool_standard_error(hdl, errno, msg);
1162 1183 }
1163 1184
1164 1185 ret = -1;
1165 1186 } else {
1166 1187 ret = 0;
1167 1188 }
1168 1189
1169 1190 zcmd_free_nvlists(&zc);
1170 1191
1171 1192 return (ret);
1172 1193 }
1173 1194
1174 1195 /*
1175 1196 * Exports the pool from the system. The caller must ensure that there are no
1176 1197 * mounted datasets in the pool.
1177 1198 */
1178 1199 int
1179 1200 zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
1180 1201 {
1181 1202 zfs_cmd_t zc = { 0 };
1182 1203 char msg[1024];
1183 1204
1184 1205 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1185 1206 "cannot export '%s'"), zhp->zpool_name);
1186 1207
1187 1208 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1188 1209 zc.zc_cookie = force;
1189 1210 zc.zc_guid = hardforce;
1190 1211
1191 1212 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
1192 1213 switch (errno) {
1193 1214 case EXDEV:
1194 1215 zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
1195 1216 "use '-f' to override the following errors:\n"
1196 1217 "'%s' has an active shared spare which could be"
1197 1218 " used by other pools once '%s' is exported."),
1198 1219 zhp->zpool_name, zhp->zpool_name);
1199 1220 return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
1200 1221 msg));
1201 1222 default:
1202 1223 return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
1203 1224 msg));
1204 1225 }
1205 1226 }
1206 1227
1207 1228 return (0);
1208 1229 }
1209 1230
1210 1231 int
1211 1232 zpool_export(zpool_handle_t *zhp, boolean_t force)
1212 1233 {
1213 1234 return (zpool_export_common(zhp, force, B_FALSE));
1214 1235 }
1215 1236
1216 1237 int
1217 1238 zpool_export_force(zpool_handle_t *zhp)
1218 1239 {
1219 1240 return (zpool_export_common(zhp, B_TRUE, B_TRUE));
1220 1241 }
1221 1242
1222 1243 static void
1223 1244 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1224 1245 nvlist_t *config)
1225 1246 {
1226 1247 nvlist_t *nv = NULL;
1227 1248 uint64_t rewindto;
1228 1249 int64_t loss = -1;
1229 1250 struct tm t;
1230 1251 char timestr[128];
1231 1252
1232 1253 if (!hdl->libzfs_printerr || config == NULL)
1233 1254 return;
1234 1255
1235 1256 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0)
1236 1257 return;
1237 1258
1238 1259 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1239 1260 return;
1240 1261 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1241 1262
1242 1263 if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1243 1264 strftime(timestr, 128, 0, &t) != 0) {
1244 1265 if (dryrun) {
1245 1266 (void) printf(dgettext(TEXT_DOMAIN,
1246 1267 "Would be able to return %s "
1247 1268 "to its state as of %s.\n"),
1248 1269 name, timestr);
1249 1270 } else {
1250 1271 (void) printf(dgettext(TEXT_DOMAIN,
1251 1272 "Pool %s returned to its state as of %s.\n"),
1252 1273 name, timestr);
1253 1274 }
1254 1275 if (loss > 120) {
1255 1276 (void) printf(dgettext(TEXT_DOMAIN,
1256 1277 "%s approximately %lld "),
1257 1278 dryrun ? "Would discard" : "Discarded",
1258 1279 (loss + 30) / 60);
1259 1280 (void) printf(dgettext(TEXT_DOMAIN,
1260 1281 "minutes of transactions.\n"));
1261 1282 } else if (loss > 0) {
1262 1283 (void) printf(dgettext(TEXT_DOMAIN,
1263 1284 "%s approximately %lld "),
1264 1285 dryrun ? "Would discard" : "Discarded", loss);
1265 1286 (void) printf(dgettext(TEXT_DOMAIN,
1266 1287 "seconds of transactions.\n"));
1267 1288 }
1268 1289 }
1269 1290 }
1270 1291
1271 1292 void
1272 1293 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
1273 1294 nvlist_t *config)
1274 1295 {
1275 1296 nvlist_t *nv = NULL;
1276 1297 int64_t loss = -1;
1277 1298 uint64_t edata = UINT64_MAX;
1278 1299 uint64_t rewindto;
1279 1300 struct tm t;
1280 1301 char timestr[128];
1281 1302
1282 1303 if (!hdl->libzfs_printerr)
1283 1304 return;
1284 1305
1285 1306 if (reason >= 0)
1286 1307 (void) printf(dgettext(TEXT_DOMAIN, "action: "));
1287 1308 else
1288 1309 (void) printf(dgettext(TEXT_DOMAIN, "\t"));
1289 1310
1290 1311 /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1291 1312 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1292 1313 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1293 1314 goto no_info;
1294 1315
1295 1316 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1296 1317 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
1297 1318 &edata);
1298 1319
1299 1320 (void) printf(dgettext(TEXT_DOMAIN,
1300 1321 "Recovery is possible, but will result in some data loss.\n"));
1301 1322
1302 1323 if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1303 1324 strftime(timestr, 128, 0, &t) != 0) {
1304 1325 (void) printf(dgettext(TEXT_DOMAIN,
1305 1326 "\tReturning the pool to its state as of %s\n"
1306 1327 "\tshould correct the problem. "),
1307 1328 timestr);
1308 1329 } else {
1309 1330 (void) printf(dgettext(TEXT_DOMAIN,
1310 1331 "\tReverting the pool to an earlier state "
1311 1332 "should correct the problem.\n\t"));
1312 1333 }
1313 1334
1314 1335 if (loss > 120) {
1315 1336 (void) printf(dgettext(TEXT_DOMAIN,
1316 1337 "Approximately %lld minutes of data\n"
1317 1338 "\tmust be discarded, irreversibly. "), (loss + 30) / 60);
1318 1339 } else if (loss > 0) {
1319 1340 (void) printf(dgettext(TEXT_DOMAIN,
1320 1341 "Approximately %lld seconds of data\n"
1321 1342 "\tmust be discarded, irreversibly. "), loss);
1322 1343 }
1323 1344 if (edata != 0 && edata != UINT64_MAX) {
1324 1345 if (edata == 1) {
1325 1346 (void) printf(dgettext(TEXT_DOMAIN,
1326 1347 "After rewind, at least\n"
1327 1348 "\tone persistent user-data error will remain. "));
1328 1349 } else {
1329 1350 (void) printf(dgettext(TEXT_DOMAIN,
1330 1351 "After rewind, several\n"
1331 1352 "\tpersistent user-data errors will remain. "));
1332 1353 }
1333 1354 }
1334 1355 (void) printf(dgettext(TEXT_DOMAIN,
1335 1356 "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "),
1336 1357 reason >= 0 ? "clear" : "import", name);
1337 1358
1338 1359 (void) printf(dgettext(TEXT_DOMAIN,
1339 1360 "A scrub of the pool\n"
1340 1361 "\tis strongly recommended after recovery.\n"));
1341 1362 return;
1342 1363
1343 1364 no_info:
1344 1365 (void) printf(dgettext(TEXT_DOMAIN,
1345 1366 "Destroy and re-create the pool from\n\ta backup source.\n"));
1346 1367 }
1347 1368
1348 1369 /*
1349 1370 * zpool_import() is a contracted interface. Should be kept the same
1350 1371 * if possible.
1351 1372 *
1352 1373 * Applications should use zpool_import_props() to import a pool with
1353 1374 * new properties value to be set.
1354 1375 */
1355 1376 int
1356 1377 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1357 1378 char *altroot)
1358 1379 {
1359 1380 nvlist_t *props = NULL;
1360 1381 int ret;
1361 1382
1362 1383 if (altroot != NULL) {
1363 1384 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
1364 1385 return (zfs_error_fmt(hdl, EZFS_NOMEM,
1365 1386 dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1366 1387 newname));
1367 1388 }
1368 1389
1369 1390 if (nvlist_add_string(props,
1370 1391 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
1371 1392 nvlist_add_string(props,
1372 1393 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
1373 1394 nvlist_free(props);
1374 1395 return (zfs_error_fmt(hdl, EZFS_NOMEM,
1375 1396 dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1376 1397 newname));
1377 1398 }
1378 1399 }
1379 1400
1380 1401 ret = zpool_import_props(hdl, config, newname, props,
1381 1402 ZFS_IMPORT_NORMAL);
1382 1403 if (props)
1383 1404 nvlist_free(props);
1384 1405 return (ret);
1385 1406 }
1386 1407
1387 1408 static void
1388 1409 print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
1389 1410 int indent)
1390 1411 {
1391 1412 nvlist_t **child;
1392 1413 uint_t c, children;
1393 1414 char *vname;
1394 1415 uint64_t is_log = 0;
1395 1416
1396 1417 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
1397 1418 &is_log);
1398 1419
1399 1420 if (name != NULL)
1400 1421 (void) printf("\t%*s%s%s\n", indent, "", name,
1401 1422 is_log ? " [log]" : "");
1402 1423
1403 1424 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1404 1425 &child, &children) != 0)
1405 1426 return;
1406 1427
1407 1428 for (c = 0; c < children; c++) {
1408 1429 vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
1409 1430 print_vdev_tree(hdl, vname, child[c], indent + 2);
1410 1431 free(vname);
1411 1432 }
1412 1433 }
1413 1434
1414 1435 /*
1415 1436 * Import the given pool using the known configuration and a list of
1416 1437 * properties to be set. The configuration should have come from
1417 1438 * zpool_find_import(). The 'newname' parameters control whether the pool
1418 1439 * is imported with a different name.
1419 1440 */
1420 1441 int
1421 1442 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1422 1443 nvlist_t *props, int flags)
1423 1444 {
1424 1445 zfs_cmd_t zc = { 0 };
1425 1446 zpool_rewind_policy_t policy;
1426 1447 nvlist_t *nv = NULL;
1427 1448 nvlist_t *nvinfo = NULL;
1428 1449 nvlist_t *missing = NULL;
1429 1450 char *thename;
1430 1451 char *origname;
1431 1452 int ret;
1432 1453 int error = 0;
1433 1454 char errbuf[1024];
1434 1455
1435 1456 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1436 1457 &origname) == 0);
1437 1458
1438 1459 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1439 1460 "cannot import pool '%s'"), origname);
1440 1461
1441 1462 if (newname != NULL) {
1442 1463 if (!zpool_name_valid(hdl, B_FALSE, newname))
1443 1464 return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
1444 1465 dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1445 1466 newname));
1446 1467 thename = (char *)newname;
1447 1468 } else {
1448 1469 thename = origname;
1449 1470 }
1450 1471
1451 1472 if (props) {
1452 1473 uint64_t version;
1453 1474 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
1454 1475
1455 1476 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
1456 1477 &version) == 0);
1457 1478
1458 1479 if ((props = zpool_valid_proplist(hdl, origname,
1459 1480 props, version, flags, errbuf)) == NULL) {
1460 1481 return (-1);
1461 1482 } else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
1462 1483 nvlist_free(props);
1463 1484 return (-1);
1464 1485 }
1465 1486 }
1466 1487
1467 1488 (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
1468 1489
1469 1490 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1470 1491 &zc.zc_guid) == 0);
1471 1492
1472 1493 if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) {
1473 1494 nvlist_free(props);
1474 1495 return (-1);
1475 1496 }
1476 1497 if (zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2) != 0) {
1477 1498 nvlist_free(props);
1478 1499 return (-1);
1479 1500 }
1480 1501
1481 1502 zc.zc_cookie = flags;
1482 1503 while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
1483 1504 errno == ENOMEM) {
1484 1505 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
1485 1506 zcmd_free_nvlists(&zc);
1486 1507 return (-1);
1487 1508 }
1488 1509 }
1489 1510 if (ret != 0)
1490 1511 error = errno;
1491 1512
1492 1513 (void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
1493 1514 zpool_get_rewind_policy(config, &policy);
1494 1515
1495 1516 if (error) {
1496 1517 char desc[1024];
1497 1518
1498 1519 /*
1499 1520 * Dry-run failed, but we print out what success
1500 1521 * looks like if we found a best txg
1501 1522 */
1502 1523 if (policy.zrp_request & ZPOOL_TRY_REWIND) {
1503 1524 zpool_rewind_exclaim(hdl, newname ? origname : thename,
1504 1525 B_TRUE, nv);
1505 1526 nvlist_free(nv);
1506 1527 return (-1);
1507 1528 }
1508 1529
1509 1530 if (newname == NULL)
1510 1531 (void) snprintf(desc, sizeof (desc),
1511 1532 dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1512 1533 thename);
1513 1534 else
1514 1535 (void) snprintf(desc, sizeof (desc),
1515 1536 dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
1516 1537 origname, thename);
1517 1538
1518 1539 switch (error) {
1519 1540 case ENOTSUP:
1520 1541 /*
1521 1542 * Unsupported version.
1522 1543 */
1523 1544 (void) zfs_error(hdl, EZFS_BADVERSION, desc);
1524 1545 break;
1525 1546
1526 1547 case EINVAL:
1527 1548 (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
1528 1549 break;
1529 1550
1530 1551 case EROFS:
1531 1552 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1532 1553 "one or more devices is read only"));
1533 1554 (void) zfs_error(hdl, EZFS_BADDEV, desc);
1534 1555 break;
1535 1556
1536 1557 case ENXIO:
1537 1558 if (nv && nvlist_lookup_nvlist(nv,
1538 1559 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
1539 1560 nvlist_lookup_nvlist(nvinfo,
1540 1561 ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
1541 1562 (void) printf(dgettext(TEXT_DOMAIN,
1542 1563 "The devices below are missing, use "
1543 1564 "'-m' to import the pool anyway:\n"));
1544 1565 print_vdev_tree(hdl, NULL, missing, 2);
1545 1566 (void) printf("\n");
1546 1567 }
1547 1568 (void) zpool_standard_error(hdl, error, desc);
1548 1569 break;
1549 1570
1550 1571 case EEXIST:
1551 1572 (void) zpool_standard_error(hdl, error, desc);
1552 1573 break;
1553 1574
1554 1575 default:
1555 1576 (void) zpool_standard_error(hdl, error, desc);
1556 1577 zpool_explain_recover(hdl,
1557 1578 newname ? origname : thename, -error, nv);
1558 1579 break;
1559 1580 }
1560 1581
1561 1582 nvlist_free(nv);
1562 1583 ret = -1;
1563 1584 } else {
1564 1585 zpool_handle_t *zhp;
1565 1586
1566 1587 /*
1567 1588 * This should never fail, but play it safe anyway.
1568 1589 */
1569 1590 if (zpool_open_silent(hdl, thename, &zhp) != 0)
1570 1591 ret = -1;
1571 1592 else if (zhp != NULL)
1572 1593 zpool_close(zhp);
1573 1594 if (policy.zrp_request &
1574 1595 (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
1575 1596 zpool_rewind_exclaim(hdl, newname ? origname : thename,
1576 1597 ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0), nv);
1577 1598 }
1578 1599 nvlist_free(nv);
1579 1600 return (0);
1580 1601 }
1581 1602
1582 1603 zcmd_free_nvlists(&zc);
1583 1604 nvlist_free(props);
1584 1605
1585 1606 return (ret);
1586 1607 }
1587 1608
1588 1609 /*
1589 1610 * Scan the pool.
1590 1611 */
1591 1612 int
1592 1613 zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
1593 1614 {
1594 1615 zfs_cmd_t zc = { 0 };
1595 1616 char msg[1024];
1596 1617 libzfs_handle_t *hdl = zhp->zpool_hdl;
1597 1618
1598 1619 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1599 1620 zc.zc_cookie = func;
1600 1621
1601 1622 if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
1602 1623 (errno == ENOENT && func != POOL_SCAN_NONE))
1603 1624 return (0);
1604 1625
1605 1626 if (func == POOL_SCAN_SCRUB) {
1606 1627 (void) snprintf(msg, sizeof (msg),
1607 1628 dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
1608 1629 } else if (func == POOL_SCAN_NONE) {
1609 1630 (void) snprintf(msg, sizeof (msg),
1610 1631 dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
1611 1632 zc.zc_name);
1612 1633 } else {
1613 1634 assert(!"unexpected result");
1614 1635 }
1615 1636
1616 1637 if (errno == EBUSY) {
1617 1638 nvlist_t *nvroot;
1618 1639 pool_scan_stat_t *ps = NULL;
1619 1640 uint_t psc;
1620 1641
1621 1642 verify(nvlist_lookup_nvlist(zhp->zpool_config,
1622 1643 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
1623 1644 (void) nvlist_lookup_uint64_array(nvroot,
1624 1645 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
1625 1646 if (ps && ps->pss_func == POOL_SCAN_SCRUB)
1626 1647 return (zfs_error(hdl, EZFS_SCRUBBING, msg));
1627 1648 else
1628 1649 return (zfs_error(hdl, EZFS_RESILVERING, msg));
1629 1650 } else if (errno == ENOENT) {
1630 1651 return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
1631 1652 } else {
1632 1653 return (zpool_standard_error(hdl, errno, msg));
1633 1654 }
1634 1655 }
1635 1656
1636 1657 /*
1637 1658 * This provides a very minimal check whether a given string is likely a
1638 1659 * c#t#d# style string. Users of this are expected to do their own
1639 1660 * verification of the s# part.
1640 1661 */
1641 1662 #define CTD_CHECK(str) (str && str[0] == 'c' && isdigit(str[1]))
1642 1663
1643 1664 /*
1644 1665 * More elaborate version for ones which may start with "/dev/dsk/"
1645 1666 * and the like.
1646 1667 */
1647 1668 static int
1648 1669 ctd_check_path(char *str) {
1649 1670 /*
1650 1671 * If it starts with a slash, check the last component.
1651 1672 */
1652 1673 if (str && str[0] == '/') {
1653 1674 char *tmp = strrchr(str, '/');
1654 1675
1655 1676 /*
1656 1677 * If it ends in "/old", check the second-to-last
1657 1678 * component of the string instead.
1658 1679 */
1659 1680 if (tmp != str && strcmp(tmp, "/old") == 0) {
1660 1681 for (tmp--; *tmp != '/'; tmp--)
1661 1682 ;
1662 1683 }
1663 1684 str = tmp + 1;
1664 1685 }
1665 1686 return (CTD_CHECK(str));
1666 1687 }
1667 1688
1668 1689 /*
1669 1690 * Find a vdev that matches the search criteria specified. We use the
1670 1691 * the nvpair name to determine how we should look for the device.
1671 1692 * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
1672 1693 * spare; but FALSE if its an INUSE spare.
1673 1694 */
1674 1695 static nvlist_t *
1675 1696 vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
1676 1697 boolean_t *l2cache, boolean_t *log)
1677 1698 {
1678 1699 uint_t c, children;
1679 1700 nvlist_t **child;
1680 1701 nvlist_t *ret;
1681 1702 uint64_t is_log;
1682 1703 char *srchkey;
1683 1704 nvpair_t *pair = nvlist_next_nvpair(search, NULL);
1684 1705
1685 1706 /* Nothing to look for */
1686 1707 if (search == NULL || pair == NULL)
1687 1708 return (NULL);
1688 1709
1689 1710 /* Obtain the key we will use to search */
1690 1711 srchkey = nvpair_name(pair);
1691 1712
1692 1713 switch (nvpair_type(pair)) {
1693 1714 case DATA_TYPE_UINT64:
1694 1715 if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
1695 1716 uint64_t srchval, theguid;
1696 1717
1697 1718 verify(nvpair_value_uint64(pair, &srchval) == 0);
1698 1719 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1699 1720 &theguid) == 0);
1700 1721 if (theguid == srchval)
1701 1722 return (nv);
1702 1723 }
1703 1724 break;
1704 1725
1705 1726 case DATA_TYPE_STRING: {
1706 1727 char *srchval, *val;
1707 1728
1708 1729 verify(nvpair_value_string(pair, &srchval) == 0);
1709 1730 if (nvlist_lookup_string(nv, srchkey, &val) != 0)
1710 1731 break;
1711 1732
1712 1733 /*
1713 1734 * Search for the requested value. Special cases:
1714 1735 *
1715 1736 * - ZPOOL_CONFIG_PATH for whole disk entries. These end in
1716 1737 * "s0" or "s0/old". The "s0" part is hidden from the user,
1717 1738 * but included in the string, so this matches around it.
1718 1739 * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
1719 1740 *
1720 1741 * Otherwise, all other searches are simple string compares.
1721 1742 */
1722 1743 if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 &&
1723 1744 ctd_check_path(val)) {
1724 1745 uint64_t wholedisk = 0;
1725 1746
1726 1747 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
1727 1748 &wholedisk);
1728 1749 if (wholedisk) {
1729 1750 int slen = strlen(srchval);
1730 1751 int vlen = strlen(val);
1731 1752
1732 1753 if (slen != vlen - 2)
1733 1754 break;
1734 1755
1735 1756 /*
1736 1757 * make_leaf_vdev() should only set
1737 1758 * wholedisk for ZPOOL_CONFIG_PATHs which
1738 1759 * will include "/dev/dsk/", giving plenty of
1739 1760 * room for the indices used next.
1740 1761 */
1741 1762 ASSERT(vlen >= 6);
1742 1763
1743 1764 /*
1744 1765 * strings identical except trailing "s0"
1745 1766 */
1746 1767 if (strcmp(&val[vlen - 2], "s0") == 0 &&
1747 1768 strncmp(srchval, val, slen) == 0)
1748 1769 return (nv);
1749 1770
1750 1771 /*
1751 1772 * strings identical except trailing "s0/old"
1752 1773 */
1753 1774 if (strcmp(&val[vlen - 6], "s0/old") == 0 &&
1754 1775 strcmp(&srchval[slen - 4], "/old") == 0 &&
1755 1776 strncmp(srchval, val, slen - 4) == 0)
1756 1777 return (nv);
1757 1778
1758 1779 break;
1759 1780 }
1760 1781 } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
1761 1782 char *type, *idx, *end, *p;
1762 1783 uint64_t id, vdev_id;
1763 1784
1764 1785 /*
1765 1786 * Determine our vdev type, keeping in mind
1766 1787 * that the srchval is composed of a type and
1767 1788 * vdev id pair (i.e. mirror-4).
1768 1789 */
1769 1790 if ((type = strdup(srchval)) == NULL)
1770 1791 return (NULL);
1771 1792
1772 1793 if ((p = strrchr(type, '-')) == NULL) {
1773 1794 free(type);
1774 1795 break;
1775 1796 }
1776 1797 idx = p + 1;
1777 1798 *p = '\0';
1778 1799
1779 1800 /*
1780 1801 * If the types don't match then keep looking.
1781 1802 */
1782 1803 if (strncmp(val, type, strlen(val)) != 0) {
1783 1804 free(type);
1784 1805 break;
1785 1806 }
1786 1807
1787 1808 verify(strncmp(type, VDEV_TYPE_RAIDZ,
1788 1809 strlen(VDEV_TYPE_RAIDZ)) == 0 ||
1789 1810 strncmp(type, VDEV_TYPE_MIRROR,
1790 1811 strlen(VDEV_TYPE_MIRROR)) == 0);
1791 1812 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
1792 1813 &id) == 0);
1793 1814
1794 1815 errno = 0;
1795 1816 vdev_id = strtoull(idx, &end, 10);
1796 1817
1797 1818 free(type);
1798 1819 if (errno != 0)
1799 1820 return (NULL);
1800 1821
1801 1822 /*
1802 1823 * Now verify that we have the correct vdev id.
1803 1824 */
1804 1825 if (vdev_id == id)
1805 1826 return (nv);
1806 1827 }
1807 1828
1808 1829 /*
1809 1830 * Common case
1810 1831 */
1811 1832 if (strcmp(srchval, val) == 0)
1812 1833 return (nv);
1813 1834 break;
1814 1835 }
1815 1836
1816 1837 default:
1817 1838 break;
1818 1839 }
1819 1840
1820 1841 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1821 1842 &child, &children) != 0)
1822 1843 return (NULL);
1823 1844
1824 1845 for (c = 0; c < children; c++) {
1825 1846 if ((ret = vdev_to_nvlist_iter(child[c], search,
1826 1847 avail_spare, l2cache, NULL)) != NULL) {
1827 1848 /*
1828 1849 * The 'is_log' value is only set for the toplevel
1829 1850 * vdev, not the leaf vdevs. So we always lookup the
1830 1851 * log device from the root of the vdev tree (where
1831 1852 * 'log' is non-NULL).
1832 1853 */
1833 1854 if (log != NULL &&
1834 1855 nvlist_lookup_uint64(child[c],
1835 1856 ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
1836 1857 is_log) {
1837 1858 *log = B_TRUE;
1838 1859 }
1839 1860 return (ret);
1840 1861 }
1841 1862 }
1842 1863
1843 1864 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1844 1865 &child, &children) == 0) {
1845 1866 for (c = 0; c < children; c++) {
1846 1867 if ((ret = vdev_to_nvlist_iter(child[c], search,
1847 1868 avail_spare, l2cache, NULL)) != NULL) {
1848 1869 *avail_spare = B_TRUE;
1849 1870 return (ret);
1850 1871 }
1851 1872 }
1852 1873 }
1853 1874
1854 1875 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1855 1876 &child, &children) == 0) {
1856 1877 for (c = 0; c < children; c++) {
1857 1878 if ((ret = vdev_to_nvlist_iter(child[c], search,
1858 1879 avail_spare, l2cache, NULL)) != NULL) {
1859 1880 *l2cache = B_TRUE;
1860 1881 return (ret);
1861 1882 }
1862 1883 }
1863 1884 }
1864 1885
1865 1886 return (NULL);
1866 1887 }
1867 1888
1868 1889 /*
1869 1890 * Given a physical path (minus the "/devices" prefix), find the
1870 1891 * associated vdev.
1871 1892 */
1872 1893 nvlist_t *
1873 1894 zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
1874 1895 boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
1875 1896 {
1876 1897 nvlist_t *search, *nvroot, *ret;
1877 1898
1878 1899 verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1879 1900 verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0);
1880 1901
1881 1902 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
1882 1903 &nvroot) == 0);
1883 1904
1884 1905 *avail_spare = B_FALSE;
1885 1906 *l2cache = B_FALSE;
1886 1907 if (log != NULL)
1887 1908 *log = B_FALSE;
1888 1909 ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
1889 1910 nvlist_free(search);
1890 1911
1891 1912 return (ret);
1892 1913 }
1893 1914
1894 1915 /*
1895 1916 * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
1896 1917 */
1897 1918 boolean_t
1898 1919 zpool_vdev_is_interior(const char *name)
1899 1920 {
1900 1921 if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
1901 1922 strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
1902 1923 return (B_TRUE);
1903 1924 return (B_FALSE);
1904 1925 }
1905 1926
1906 1927 nvlist_t *
1907 1928 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
1908 1929 boolean_t *l2cache, boolean_t *log)
1909 1930 {
1910 1931 char buf[MAXPATHLEN];
1911 1932 char *end;
1912 1933 nvlist_t *nvroot, *search, *ret;
1913 1934 uint64_t guid;
1914 1935
1915 1936 verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1916 1937
1917 1938 guid = strtoull(path, &end, 10);
1918 1939 if (guid != 0 && *end == '\0') {
1919 1940 verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
1920 1941 } else if (zpool_vdev_is_interior(path)) {
1921 1942 verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
1922 1943 } else if (path[0] != '/') {
1923 1944 (void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path);
1924 1945 verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
1925 1946 } else {
1926 1947 verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
1927 1948 }
1928 1949
1929 1950 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
1930 1951 &nvroot) == 0);
1931 1952
1932 1953 *avail_spare = B_FALSE;
1933 1954 *l2cache = B_FALSE;
1934 1955 if (log != NULL)
1935 1956 *log = B_FALSE;
1936 1957 ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
1937 1958 nvlist_free(search);
1938 1959
1939 1960 return (ret);
1940 1961 }
1941 1962
1942 1963 static int
1943 1964 vdev_online(nvlist_t *nv)
1944 1965 {
1945 1966 uint64_t ival;
1946 1967
1947 1968 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
1948 1969 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
1949 1970 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
1950 1971 return (0);
1951 1972
1952 1973 return (1);
1953 1974 }
1954 1975
1955 1976 /*
1956 1977 * Helper function for zpool_get_physpaths().
1957 1978 */
1958 1979 static int
1959 1980 vdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
1960 1981 size_t *bytes_written)
1961 1982 {
1962 1983 size_t bytes_left, pos, rsz;
1963 1984 char *tmppath;
1964 1985 const char *format;
1965 1986
1966 1987 if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
1967 1988 &tmppath) != 0)
1968 1989 return (EZFS_NODEVICE);
1969 1990
1970 1991 pos = *bytes_written;
1971 1992 bytes_left = physpath_size - pos;
1972 1993 format = (pos == 0) ? "%s" : " %s";
1973 1994
1974 1995 rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
1975 1996 *bytes_written += rsz;
1976 1997
1977 1998 if (rsz >= bytes_left) {
1978 1999 /* if physpath was not copied properly, clear it */
1979 2000 if (bytes_left != 0) {
1980 2001 physpath[pos] = 0;
1981 2002 }
1982 2003 return (EZFS_NOSPC);
1983 2004 }
1984 2005 return (0);
1985 2006 }
1986 2007
1987 2008 static int
1988 2009 vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
1989 2010 size_t *rsz, boolean_t is_spare)
1990 2011 {
1991 2012 char *type;
1992 2013 int ret;
1993 2014
1994 2015 if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
1995 2016 return (EZFS_INVALCONFIG);
1996 2017
1997 2018 if (strcmp(type, VDEV_TYPE_DISK) == 0) {
1998 2019 /*
1999 2020 * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
2000 2021 * For a spare vdev, we only want to boot from the active
2001 2022 * spare device.
2002 2023 */
2003 2024 if (is_spare) {
2004 2025 uint64_t spare = 0;
2005 2026 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
2006 2027 &spare);
2007 2028 if (!spare)
2008 2029 return (EZFS_INVALCONFIG);
2009 2030 }
2010 2031
2011 2032 if (vdev_online(nv)) {
2012 2033 if ((ret = vdev_get_one_physpath(nv, physpath,
2013 2034 phypath_size, rsz)) != 0)
2014 2035 return (ret);
2015 2036 }
2016 2037 } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
2017 2038 strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
2018 2039 (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
2019 2040 nvlist_t **child;
2020 2041 uint_t count;
2021 2042 int i, ret;
2022 2043
2023 2044 if (nvlist_lookup_nvlist_array(nv,
2024 2045 ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
2025 2046 return (EZFS_INVALCONFIG);
2026 2047
2027 2048 for (i = 0; i < count; i++) {
2028 2049 ret = vdev_get_physpaths(child[i], physpath,
2029 2050 phypath_size, rsz, is_spare);
2030 2051 if (ret == EZFS_NOSPC)
2031 2052 return (ret);
2032 2053 }
2033 2054 }
2034 2055
2035 2056 return (EZFS_POOL_INVALARG);
2036 2057 }
2037 2058
2038 2059 /*
2039 2060 * Get phys_path for a root pool config.
2040 2061 * Return 0 on success; non-zero on failure.
2041 2062 */
2042 2063 static int
2043 2064 zpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
2044 2065 {
2045 2066 size_t rsz;
2046 2067 nvlist_t *vdev_root;
2047 2068 nvlist_t **child;
2048 2069 uint_t count;
2049 2070 char *type;
2050 2071
2051 2072 rsz = 0;
2052 2073
2053 2074 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2054 2075 &vdev_root) != 0)
2055 2076 return (EZFS_INVALCONFIG);
2056 2077
2057 2078 if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
2058 2079 nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
2059 2080 &child, &count) != 0)
2060 2081 return (EZFS_INVALCONFIG);
2061 2082
2062 2083 /*
2063 2084 * root pool can not have EFI labeled disks and can only have
2064 2085 * a single top-level vdev.
2065 2086 */
2066 2087 if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1 ||
2067 2088 pool_uses_efi(vdev_root))
2068 2089 return (EZFS_POOL_INVALARG);
2069 2090
2070 2091 (void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
2071 2092 B_FALSE);
2072 2093
2073 2094 /* No online devices */
2074 2095 if (rsz == 0)
2075 2096 return (EZFS_NODEVICE);
2076 2097
2077 2098 return (0);
2078 2099 }
2079 2100
2080 2101 /*
2081 2102 * Get phys_path for a root pool
2082 2103 * Return 0 on success; non-zero on failure.
2083 2104 */
2084 2105 int
2085 2106 zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
2086 2107 {
2087 2108 return (zpool_get_config_physpath(zhp->zpool_config, physpath,
2088 2109 phypath_size));
2089 2110 }
2090 2111
2091 2112 /*
2092 2113 * If the device has being dynamically expanded then we need to relabel
2093 2114 * the disk to use the new unallocated space.
2094 2115 */
2095 2116 static int
2096 2117 zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
2097 2118 {
2098 2119 char path[MAXPATHLEN];
2099 2120 char errbuf[1024];
2100 2121 int fd, error;
2101 2122 int (*_efi_use_whole_disk)(int);
2102 2123
2103 2124 if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
2104 2125 "efi_use_whole_disk")) == NULL)
2105 2126 return (-1);
2106 2127
2107 2128 (void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
2108 2129
2109 2130 if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
2110 2131 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
2111 2132 "relabel '%s': unable to open device"), name);
2112 2133 return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
2113 2134 }
2114 2135
2115 2136 /*
2116 2137 * It's possible that we might encounter an error if the device
2117 2138 * does not have any unallocated space left. If so, we simply
2118 2139 * ignore that error and continue on.
2119 2140 */
2120 2141 error = _efi_use_whole_disk(fd);
2121 2142 (void) close(fd);
2122 2143 if (error && error != VT_ENOSPC) {
2123 2144 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
2124 2145 "relabel '%s': unable to read disk capacity"), name);
2125 2146 return (zfs_error(hdl, EZFS_NOCAP, errbuf));
2126 2147 }
2127 2148 return (0);
2128 2149 }
2129 2150
2130 2151 /*
2131 2152 * Bring the specified vdev online. The 'flags' parameter is a set of the
2132 2153 * ZFS_ONLINE_* flags.
2133 2154 */
2134 2155 int
2135 2156 zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
2136 2157 vdev_state_t *newstate)
2137 2158 {
2138 2159 zfs_cmd_t zc = { 0 };
2139 2160 char msg[1024];
2140 2161 nvlist_t *tgt;
2141 2162 boolean_t avail_spare, l2cache, islog;
2142 2163 libzfs_handle_t *hdl = zhp->zpool_hdl;
2143 2164
2144 2165 if (flags & ZFS_ONLINE_EXPAND) {
2145 2166 (void) snprintf(msg, sizeof (msg),
2146 2167 dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
2147 2168 } else {
2148 2169 (void) snprintf(msg, sizeof (msg),
2149 2170 dgettext(TEXT_DOMAIN, "cannot online %s"), path);
2150 2171 }
2151 2172
2152 2173 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2153 2174 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2154 2175 &islog)) == NULL)
2155 2176 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2156 2177
2157 2178 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2158 2179
2159 2180 if (avail_spare)
2160 2181 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2161 2182
2162 2183 if (flags & ZFS_ONLINE_EXPAND ||
2163 2184 zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
2164 2185 char *pathname = NULL;
2165 2186 uint64_t wholedisk = 0;
2166 2187
2167 2188 (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
2168 2189 &wholedisk);
2169 2190 verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
2170 2191 &pathname) == 0);
2171 2192
2172 2193 /*
2173 2194 * XXX - L2ARC 1.0 devices can't support expansion.
2174 2195 */
2175 2196 if (l2cache) {
2176 2197 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2177 2198 "cannot expand cache devices"));
2178 2199 return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
2179 2200 }
2180 2201
2181 2202 if (wholedisk) {
2182 2203 pathname += strlen(DISK_ROOT) + 1;
2183 2204 (void) zpool_relabel_disk(hdl, pathname);
2184 2205 }
2185 2206 }
2186 2207
2187 2208 zc.zc_cookie = VDEV_STATE_ONLINE;
2188 2209 zc.zc_obj = flags;
2189 2210
2190 2211 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
2191 2212 if (errno == EINVAL) {
2192 2213 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
2193 2214 "from this pool into a new one. Use '%s' "
2194 2215 "instead"), "zpool detach");
2195 2216 return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, msg));
2196 2217 }
2197 2218 return (zpool_standard_error(hdl, errno, msg));
2198 2219 }
2199 2220
2200 2221 *newstate = zc.zc_cookie;
2201 2222 return (0);
2202 2223 }
2203 2224
2204 2225 /*
2205 2226 * Take the specified vdev offline
2206 2227 */
2207 2228 int
2208 2229 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
2209 2230 {
2210 2231 zfs_cmd_t zc = { 0 };
2211 2232 char msg[1024];
2212 2233 nvlist_t *tgt;
2213 2234 boolean_t avail_spare, l2cache;
2214 2235 libzfs_handle_t *hdl = zhp->zpool_hdl;
2215 2236
2216 2237 (void) snprintf(msg, sizeof (msg),
2217 2238 dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
2218 2239
2219 2240 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2220 2241 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2221 2242 NULL)) == NULL)
2222 2243 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2223 2244
2224 2245 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2225 2246
2226 2247 if (avail_spare)
2227 2248 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2228 2249
2229 2250 zc.zc_cookie = VDEV_STATE_OFFLINE;
2230 2251 zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
2231 2252
2232 2253 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2233 2254 return (0);
2234 2255
2235 2256 switch (errno) {
2236 2257 case EBUSY:
2237 2258
2238 2259 /*
2239 2260 * There are no other replicas of this device.
2240 2261 */
2241 2262 return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
2242 2263
2243 2264 case EEXIST:
2244 2265 /*
2245 2266 * The log device has unplayed logs
2246 2267 */
2247 2268 return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
2248 2269
2249 2270 default:
2250 2271 return (zpool_standard_error(hdl, errno, msg));
2251 2272 }
2252 2273 }
2253 2274
2254 2275 /*
2255 2276 * Mark the given vdev faulted.
2256 2277 */
2257 2278 int
2258 2279 zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
2259 2280 {
2260 2281 zfs_cmd_t zc = { 0 };
2261 2282 char msg[1024];
2262 2283 libzfs_handle_t *hdl = zhp->zpool_hdl;
2263 2284
2264 2285 (void) snprintf(msg, sizeof (msg),
2265 2286 dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid);
2266 2287
2267 2288 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2268 2289 zc.zc_guid = guid;
2269 2290 zc.zc_cookie = VDEV_STATE_FAULTED;
2270 2291 zc.zc_obj = aux;
2271 2292
2272 2293 if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2273 2294 return (0);
2274 2295
2275 2296 switch (errno) {
2276 2297 case EBUSY:
2277 2298
2278 2299 /*
2279 2300 * There are no other replicas of this device.
2280 2301 */
2281 2302 return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
2282 2303
2283 2304 default:
2284 2305 return (zpool_standard_error(hdl, errno, msg));
2285 2306 }
2286 2307
2287 2308 }
2288 2309
2289 2310 /*
2290 2311 * Mark the given vdev degraded.
2291 2312 */
2292 2313 int
2293 2314 zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
2294 2315 {
2295 2316 zfs_cmd_t zc = { 0 };
2296 2317 char msg[1024];
2297 2318 libzfs_handle_t *hdl = zhp->zpool_hdl;
2298 2319
2299 2320 (void) snprintf(msg, sizeof (msg),
2300 2321 dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
2301 2322
2302 2323 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2303 2324 zc.zc_guid = guid;
2304 2325 zc.zc_cookie = VDEV_STATE_DEGRADED;
2305 2326 zc.zc_obj = aux;
2306 2327
2307 2328 if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2308 2329 return (0);
2309 2330
2310 2331 return (zpool_standard_error(hdl, errno, msg));
2311 2332 }
2312 2333
2313 2334 /*
2314 2335 * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
2315 2336 * a hot spare.
2316 2337 */
2317 2338 static boolean_t
2318 2339 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
2319 2340 {
2320 2341 nvlist_t **child;
2321 2342 uint_t c, children;
2322 2343 char *type;
2323 2344
2324 2345 if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
2325 2346 &children) == 0) {
2326 2347 verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
2327 2348 &type) == 0);
2328 2349
2329 2350 if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
2330 2351 children == 2 && child[which] == tgt)
2331 2352 return (B_TRUE);
2332 2353
2333 2354 for (c = 0; c < children; c++)
2334 2355 if (is_replacing_spare(child[c], tgt, which))
2335 2356 return (B_TRUE);
2336 2357 }
2337 2358
2338 2359 return (B_FALSE);
2339 2360 }
2340 2361
2341 2362 /*
2342 2363 * Attach new_disk (fully described by nvroot) to old_disk.
2343 2364 * If 'replacing' is specified, the new disk will replace the old one.
2344 2365 */
2345 2366 int
2346 2367 zpool_vdev_attach(zpool_handle_t *zhp,
2347 2368 const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
2348 2369 {
2349 2370 zfs_cmd_t zc = { 0 };
2350 2371 char msg[1024];
2351 2372 int ret;
2352 2373 nvlist_t *tgt;
2353 2374 boolean_t avail_spare, l2cache, islog;
2354 2375 uint64_t val;
2355 2376 char *newname;
2356 2377 nvlist_t **child;
2357 2378 uint_t children;
2358 2379 nvlist_t *config_root;
2359 2380 libzfs_handle_t *hdl = zhp->zpool_hdl;
2360 2381 boolean_t rootpool = pool_is_bootable(zhp);
2361 2382
2362 2383 if (replacing)
2363 2384 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2364 2385 "cannot replace %s with %s"), old_disk, new_disk);
2365 2386 else
2366 2387 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2367 2388 "cannot attach %s to %s"), new_disk, old_disk);
2368 2389
2369 2390 /*
2370 2391 * If this is a root pool, make sure that we're not attaching an
2371 2392 * EFI labeled device.
2372 2393 */
2373 2394 if (rootpool && pool_uses_efi(nvroot)) {
2374 2395 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2375 2396 "EFI labeled devices are not supported on root pools."));
2376 2397 return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
2377 2398 }
2378 2399
2379 2400 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2380 2401 if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
2381 2402 &islog)) == 0)
2382 2403 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2383 2404
2384 2405 if (avail_spare)
2385 2406 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2386 2407
2387 2408 if (l2cache)
2388 2409 return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
2389 2410
2390 2411 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2391 2412 zc.zc_cookie = replacing;
2392 2413
2393 2414 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
2394 2415 &child, &children) != 0 || children != 1) {
2395 2416 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2396 2417 "new device must be a single disk"));
2397 2418 return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
2398 2419 }
2399 2420
2400 2421 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
2401 2422 ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
2402 2423
2403 2424 if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
2404 2425 return (-1);
2405 2426
2406 2427 /*
2407 2428 * If the target is a hot spare that has been swapped in, we can only
2408 2429 * replace it with another hot spare.
2409 2430 */
2410 2431 if (replacing &&
2411 2432 nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
2412 2433 (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
2413 2434 NULL) == NULL || !avail_spare) &&
2414 2435 is_replacing_spare(config_root, tgt, 1)) {
2415 2436 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2416 2437 "can only be replaced by another hot spare"));
2417 2438 free(newname);
2418 2439 return (zfs_error(hdl, EZFS_BADTARGET, msg));
2419 2440 }
2420 2441
2421 2442 free(newname);
2422 2443
2423 2444 if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
2424 2445 return (-1);
2425 2446
2426 2447 ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
2427 2448
2428 2449 zcmd_free_nvlists(&zc);
2429 2450
2430 2451 if (ret == 0) {
2431 2452 if (rootpool) {
2432 2453 /*
2433 2454 * XXX need a better way to prevent user from
2434 2455 * booting up a half-baked vdev.
2435 2456 */
2436 2457 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
2437 2458 "sure to wait until resilver is done "
2438 2459 "before rebooting.\n"));
2439 2460 }
2440 2461 return (0);
2441 2462 }
2442 2463
2443 2464 switch (errno) {
2444 2465 case ENOTSUP:
2445 2466 /*
2446 2467 * Can't attach to or replace this type of vdev.
2447 2468 */
2448 2469 if (replacing) {
2449 2470 uint64_t version = zpool_get_prop_int(zhp,
2450 2471 ZPOOL_PROP_VERSION, NULL);
2451 2472
2452 2473 if (islog)
2453 2474 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2454 2475 "cannot replace a log with a spare"));
2455 2476 else if (version >= SPA_VERSION_MULTI_REPLACE)
2456 2477 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2457 2478 "already in replacing/spare config; wait "
2458 2479 "for completion or use 'zpool detach'"));
2459 2480 else
2460 2481 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2461 2482 "cannot replace a replacing device"));
2462 2483 } else {
2463 2484 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2464 2485 "can only attach to mirrors and top-level "
2465 2486 "disks"));
2466 2487 }
2467 2488 (void) zfs_error(hdl, EZFS_BADTARGET, msg);
2468 2489 break;
2469 2490
2470 2491 case EINVAL:
2471 2492 /*
2472 2493 * The new device must be a single disk.
2473 2494 */
2474 2495 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2475 2496 "new device must be a single disk"));
2476 2497 (void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
2477 2498 break;
2478 2499
2479 2500 case EBUSY:
2480 2501 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
2481 2502 new_disk);
2482 2503 (void) zfs_error(hdl, EZFS_BADDEV, msg);
2483 2504 break;
2484 2505
2485 2506 case EOVERFLOW:
2486 2507 /*
2487 2508 * The new device is too small.
2488 2509 */
2489 2510 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2490 2511 "device is too small"));
2491 2512 (void) zfs_error(hdl, EZFS_BADDEV, msg);
2492 2513 break;
2493 2514
2494 2515 case EDOM:
2495 2516 /*
2496 2517 * The new device has a different alignment requirement.
2497 2518 */
2498 2519 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2499 2520 "devices have different sector alignment"));
2500 2521 (void) zfs_error(hdl, EZFS_BADDEV, msg);
2501 2522 break;
2502 2523
2503 2524 case ENAMETOOLONG:
2504 2525 /*
2505 2526 * The resulting top-level vdev spec won't fit in the label.
2506 2527 */
2507 2528 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
2508 2529 break;
2509 2530
2510 2531 default:
2511 2532 (void) zpool_standard_error(hdl, errno, msg);
2512 2533 }
2513 2534
2514 2535 return (-1);
2515 2536 }
2516 2537
2517 2538 /*
2518 2539 * Detach the specified device.
2519 2540 */
2520 2541 int
2521 2542 zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
2522 2543 {
2523 2544 zfs_cmd_t zc = { 0 };
2524 2545 char msg[1024];
2525 2546 nvlist_t *tgt;
2526 2547 boolean_t avail_spare, l2cache;
2527 2548 libzfs_handle_t *hdl = zhp->zpool_hdl;
2528 2549
2529 2550 (void) snprintf(msg, sizeof (msg),
2530 2551 dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
2531 2552
2532 2553 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2533 2554 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2534 2555 NULL)) == 0)
2535 2556 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2536 2557
2537 2558 if (avail_spare)
2538 2559 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2539 2560
2540 2561 if (l2cache)
2541 2562 return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
2542 2563
2543 2564 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2544 2565
2545 2566 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
2546 2567 return (0);
2547 2568
2548 2569 switch (errno) {
2549 2570
2550 2571 case ENOTSUP:
2551 2572 /*
2552 2573 * Can't detach from this type of vdev.
2553 2574 */
2554 2575 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
2555 2576 "applicable to mirror and replacing vdevs"));
2556 2577 (void) zfs_error(hdl, EZFS_BADTARGET, msg);
2557 2578 break;
2558 2579
2559 2580 case EBUSY:
2560 2581 /*
2561 2582 * There are no other replicas of this device.
2562 2583 */
2563 2584 (void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
2564 2585 break;
2565 2586
2566 2587 default:
2567 2588 (void) zpool_standard_error(hdl, errno, msg);
2568 2589 }
2569 2590
2570 2591 return (-1);
2571 2592 }
2572 2593
2573 2594 /*
2574 2595 * Find a mirror vdev in the source nvlist.
2575 2596 *
2576 2597 * The mchild array contains a list of disks in one of the top-level mirrors
2577 2598 * of the source pool. The schild array contains a list of disks that the
2578 2599 * user specified on the command line. We loop over the mchild array to
2579 2600 * see if any entry in the schild array matches.
2580 2601 *
2581 2602 * If a disk in the mchild array is found in the schild array, we return
2582 2603 * the index of that entry. Otherwise we return -1.
2583 2604 */
2584 2605 static int
2585 2606 find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
2586 2607 nvlist_t **schild, uint_t schildren)
2587 2608 {
2588 2609 uint_t mc;
2589 2610
2590 2611 for (mc = 0; mc < mchildren; mc++) {
2591 2612 uint_t sc;
2592 2613 char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
2593 2614 mchild[mc], B_FALSE);
2594 2615
2595 2616 for (sc = 0; sc < schildren; sc++) {
2596 2617 char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
2597 2618 schild[sc], B_FALSE);
2598 2619 boolean_t result = (strcmp(mpath, spath) == 0);
2599 2620
2600 2621 free(spath);
2601 2622 if (result) {
2602 2623 free(mpath);
2603 2624 return (mc);
2604 2625 }
2605 2626 }
2606 2627
2607 2628 free(mpath);
2608 2629 }
2609 2630
2610 2631 return (-1);
2611 2632 }
2612 2633
2613 2634 /*
2614 2635 * Split a mirror pool. If newroot points to null, then a new nvlist
2615 2636 * is generated and it is the responsibility of the caller to free it.
2616 2637 */
2617 2638 int
2618 2639 zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
2619 2640 nvlist_t *props, splitflags_t flags)
2620 2641 {
2621 2642 zfs_cmd_t zc = { 0 };
2622 2643 char msg[1024];
2623 2644 nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
2624 2645 nvlist_t **varray = NULL, *zc_props = NULL;
2625 2646 uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
2626 2647 libzfs_handle_t *hdl = zhp->zpool_hdl;
2627 2648 uint64_t vers;
2628 2649 boolean_t freelist = B_FALSE, memory_err = B_TRUE;
2629 2650 int retval = 0;
2630 2651
2631 2652 (void) snprintf(msg, sizeof (msg),
2632 2653 dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
2633 2654
2634 2655 if (!zpool_name_valid(hdl, B_FALSE, newname))
2635 2656 return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
2636 2657
2637 2658 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
2638 2659 (void) fprintf(stderr, gettext("Internal error: unable to "
2639 2660 "retrieve pool configuration\n"));
2640 2661 return (-1);
2641 2662 }
2642 2663
2643 2664 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree)
2644 2665 == 0);
2645 2666 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &vers) == 0);
2646 2667
2647 2668 if (props) {
2648 2669 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
2649 2670 if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
2650 2671 props, vers, flags, msg)) == NULL)
2651 2672 return (-1);
2652 2673 }
2653 2674
2654 2675 if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
2655 2676 &children) != 0) {
2656 2677 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2657 2678 "Source pool is missing vdev tree"));
2658 2679 if (zc_props)
2659 2680 nvlist_free(zc_props);
2660 2681 return (-1);
2661 2682 }
2662 2683
2663 2684 varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
2664 2685 vcount = 0;
2665 2686
2666 2687 if (*newroot == NULL ||
2667 2688 nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
2668 2689 &newchild, &newchildren) != 0)
2669 2690 newchildren = 0;
2670 2691
2671 2692 for (c = 0; c < children; c++) {
2672 2693 uint64_t is_log = B_FALSE, is_hole = B_FALSE;
2673 2694 char *type;
2674 2695 nvlist_t **mchild, *vdev;
2675 2696 uint_t mchildren;
2676 2697 int entry;
2677 2698
2678 2699 /*
2679 2700 * Unlike cache & spares, slogs are stored in the
2680 2701 * ZPOOL_CONFIG_CHILDREN array. We filter them out here.
2681 2702 */
2682 2703 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2683 2704 &is_log);
2684 2705 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
2685 2706 &is_hole);
2686 2707 if (is_log || is_hole) {
2687 2708 /*
2688 2709 * Create a hole vdev and put it in the config.
2689 2710 */
2690 2711 if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
2691 2712 goto out;
2692 2713 if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
2693 2714 VDEV_TYPE_HOLE) != 0)
2694 2715 goto out;
2695 2716 if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
2696 2717 1) != 0)
2697 2718 goto out;
2698 2719 if (lastlog == 0)
2699 2720 lastlog = vcount;
2700 2721 varray[vcount++] = vdev;
2701 2722 continue;
2702 2723 }
2703 2724 lastlog = 0;
2704 2725 verify(nvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE, &type)
2705 2726 == 0);
2706 2727 if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
2707 2728 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2708 2729 "Source pool must be composed only of mirrors\n"));
2709 2730 retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
2710 2731 goto out;
2711 2732 }
2712 2733
2713 2734 verify(nvlist_lookup_nvlist_array(child[c],
2714 2735 ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
2715 2736
2716 2737 /* find or add an entry for this top-level vdev */
2717 2738 if (newchildren > 0 &&
2718 2739 (entry = find_vdev_entry(zhp, mchild, mchildren,
2719 2740 newchild, newchildren)) >= 0) {
2720 2741 /* We found a disk that the user specified. */
2721 2742 vdev = mchild[entry];
2722 2743 ++found;
2723 2744 } else {
2724 2745 /* User didn't specify a disk for this vdev. */
2725 2746 vdev = mchild[mchildren - 1];
2726 2747 }
2727 2748
2728 2749 if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
2729 2750 goto out;
2730 2751 }
2731 2752
2732 2753 /* did we find every disk the user specified? */
2733 2754 if (found != newchildren) {
2734 2755 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
2735 2756 "include at most one disk from each mirror"));
2736 2757 retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
2737 2758 goto out;
2738 2759 }
2739 2760
2740 2761 /* Prepare the nvlist for populating. */
2741 2762 if (*newroot == NULL) {
2742 2763 if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
2743 2764 goto out;
2744 2765 freelist = B_TRUE;
2745 2766 if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
2746 2767 VDEV_TYPE_ROOT) != 0)
2747 2768 goto out;
2748 2769 } else {
2749 2770 verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
2750 2771 }
2751 2772
2752 2773 /* Add all the children we found */
2753 2774 if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN, varray,
2754 2775 lastlog == 0 ? vcount : lastlog) != 0)
2755 2776 goto out;
2756 2777
2757 2778 /*
2758 2779 * If we're just doing a dry run, exit now with success.
2759 2780 */
2760 2781 if (flags.dryrun) {
2761 2782 memory_err = B_FALSE;
2762 2783 freelist = B_FALSE;
2763 2784 goto out;
2764 2785 }
2765 2786
2766 2787 /* now build up the config list & call the ioctl */
2767 2788 if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
2768 2789 goto out;
2769 2790
2770 2791 if (nvlist_add_nvlist(newconfig,
2771 2792 ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
2772 2793 nvlist_add_string(newconfig,
2773 2794 ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
2774 2795 nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
2775 2796 goto out;
2776 2797
2777 2798 /*
2778 2799 * The new pool is automatically part of the namespace unless we
2779 2800 * explicitly export it.
2780 2801 */
2781 2802 if (!flags.import)
2782 2803 zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
2783 2804 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2784 2805 (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
2785 2806 if (zcmd_write_conf_nvlist(hdl, &zc, newconfig) != 0)
2786 2807 goto out;
2787 2808 if (zc_props != NULL && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
2788 2809 goto out;
2789 2810
2790 2811 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
2791 2812 retval = zpool_standard_error(hdl, errno, msg);
2792 2813 goto out;
2793 2814 }
2794 2815
2795 2816 freelist = B_FALSE;
2796 2817 memory_err = B_FALSE;
2797 2818
2798 2819 out:
2799 2820 if (varray != NULL) {
2800 2821 int v;
2801 2822
2802 2823 for (v = 0; v < vcount; v++)
2803 2824 nvlist_free(varray[v]);
2804 2825 free(varray);
2805 2826 }
2806 2827 zcmd_free_nvlists(&zc);
2807 2828 if (zc_props)
2808 2829 nvlist_free(zc_props);
2809 2830 if (newconfig)
2810 2831 nvlist_free(newconfig);
2811 2832 if (freelist) {
2812 2833 nvlist_free(*newroot);
2813 2834 *newroot = NULL;
2814 2835 }
2815 2836
2816 2837 if (retval != 0)
2817 2838 return (retval);
2818 2839
2819 2840 if (memory_err)
2820 2841 return (no_memory(hdl));
2821 2842
2822 2843 return (0);
2823 2844 }
2824 2845
2825 2846 /*
2826 2847 * Remove the given device. Currently, this is supported only for hot spares
2827 2848 * and level 2 cache devices.
2828 2849 */
2829 2850 int
2830 2851 zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
2831 2852 {
2832 2853 zfs_cmd_t zc = { 0 };
2833 2854 char msg[1024];
2834 2855 nvlist_t *tgt;
2835 2856 boolean_t avail_spare, l2cache, islog;
2836 2857 libzfs_handle_t *hdl = zhp->zpool_hdl;
2837 2858 uint64_t version;
2838 2859
2839 2860 (void) snprintf(msg, sizeof (msg),
2840 2861 dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
2841 2862
2842 2863 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2843 2864 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2844 2865 &islog)) == 0)
2845 2866 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2846 2867 /*
2847 2868 * XXX - this should just go away.
2848 2869 */
2849 2870 if (!avail_spare && !l2cache && !islog) {
2850 2871 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2851 2872 "only inactive hot spares, cache, top-level, "
2852 2873 "or log devices can be removed"));
2853 2874 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2854 2875 }
2855 2876
2856 2877 version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
2857 2878 if (islog && version < SPA_VERSION_HOLES) {
2858 2879 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2859 2880 "pool must be upgrade to support log removal"));
2860 2881 return (zfs_error(hdl, EZFS_BADVERSION, msg));
2861 2882 }
2862 2883
2863 2884 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2864 2885
2865 2886 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
2866 2887 return (0);
2867 2888
2868 2889 return (zpool_standard_error(hdl, errno, msg));
2869 2890 }
2870 2891
2871 2892 /*
2872 2893 * Clear the errors for the pool, or the particular device if specified.
2873 2894 */
2874 2895 int
2875 2896 zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
2876 2897 {
2877 2898 zfs_cmd_t zc = { 0 };
2878 2899 char msg[1024];
2879 2900 nvlist_t *tgt;
2880 2901 zpool_rewind_policy_t policy;
2881 2902 boolean_t avail_spare, l2cache;
2882 2903 libzfs_handle_t *hdl = zhp->zpool_hdl;
2883 2904 nvlist_t *nvi = NULL;
2884 2905 int error;
2885 2906
2886 2907 if (path)
2887 2908 (void) snprintf(msg, sizeof (msg),
2888 2909 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
2889 2910 path);
2890 2911 else
2891 2912 (void) snprintf(msg, sizeof (msg),
2892 2913 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
2893 2914 zhp->zpool_name);
2894 2915
2895 2916 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2896 2917 if (path) {
2897 2918 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
2898 2919 &l2cache, NULL)) == 0)
2899 2920 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2900 2921
2901 2922 /*
2902 2923 * Don't allow error clearing for hot spares. Do allow
2903 2924 * error clearing for l2cache devices.
2904 2925 */
2905 2926 if (avail_spare)
2906 2927 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2907 2928
2908 2929 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
2909 2930 &zc.zc_guid) == 0);
2910 2931 }
2911 2932
2912 2933 zpool_get_rewind_policy(rewindnvl, &policy);
2913 2934 zc.zc_cookie = policy.zrp_request;
2914 2935
2915 2936 if (zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2) != 0)
2916 2937 return (-1);
2917 2938
2918 2939 if (zcmd_write_src_nvlist(hdl, &zc, rewindnvl) != 0)
2919 2940 return (-1);
2920 2941
2921 2942 while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
2922 2943 errno == ENOMEM) {
2923 2944 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
2924 2945 zcmd_free_nvlists(&zc);
2925 2946 return (-1);
2926 2947 }
2927 2948 }
2928 2949
2929 2950 if (!error || ((policy.zrp_request & ZPOOL_TRY_REWIND) &&
2930 2951 errno != EPERM && errno != EACCES)) {
2931 2952 if (policy.zrp_request &
2932 2953 (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
2933 2954 (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
2934 2955 zpool_rewind_exclaim(hdl, zc.zc_name,
2935 2956 ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
2936 2957 nvi);
2937 2958 nvlist_free(nvi);
2938 2959 }
2939 2960 zcmd_free_nvlists(&zc);
2940 2961 return (0);
2941 2962 }
2942 2963
2943 2964 zcmd_free_nvlists(&zc);
2944 2965 return (zpool_standard_error(hdl, errno, msg));
2945 2966 }
2946 2967
2947 2968 /*
2948 2969 * Similar to zpool_clear(), but takes a GUID (used by fmd).
2949 2970 */
2950 2971 int
2951 2972 zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
2952 2973 {
2953 2974 zfs_cmd_t zc = { 0 };
2954 2975 char msg[1024];
2955 2976 libzfs_handle_t *hdl = zhp->zpool_hdl;
2956 2977
2957 2978 (void) snprintf(msg, sizeof (msg),
2958 2979 dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
2959 2980 guid);
2960 2981
2961 2982 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2962 2983 zc.zc_guid = guid;
2963 2984 zc.zc_cookie = ZPOOL_NO_REWIND;
2964 2985
2965 2986 if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
2966 2987 return (0);
2967 2988
2968 2989 return (zpool_standard_error(hdl, errno, msg));
2969 2990 }
2970 2991
2971 2992 /*
2972 2993 * Change the GUID for a pool.
2973 2994 */
2974 2995 int
2975 2996 zpool_reguid(zpool_handle_t *zhp)
2976 2997 {
2977 2998 char msg[1024];
2978 2999 libzfs_handle_t *hdl = zhp->zpool_hdl;
2979 3000 zfs_cmd_t zc = { 0 };
2980 3001
2981 3002 (void) snprintf(msg, sizeof (msg),
2982 3003 dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
2983 3004
2984 3005 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2985 3006 if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0)
2986 3007 return (0);
2987 3008
2988 3009 return (zpool_standard_error(hdl, errno, msg));
2989 3010 }
2990 3011
2991 3012 /*
2992 3013 * Convert from a devid string to a path.
2993 3014 */
2994 3015 static char *
2995 3016 devid_to_path(char *devid_str)
2996 3017 {
2997 3018 ddi_devid_t devid;
2998 3019 char *minor;
2999 3020 char *path;
3000 3021 devid_nmlist_t *list = NULL;
3001 3022 int ret;
3002 3023
3003 3024 if (devid_str_decode(devid_str, &devid, &minor) != 0)
3004 3025 return (NULL);
3005 3026
3006 3027 ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
3007 3028
3008 3029 devid_str_free(minor);
3009 3030 devid_free(devid);
3010 3031
3011 3032 if (ret != 0)
3012 3033 return (NULL);
3013 3034
3014 3035 if ((path = strdup(list[0].devname)) == NULL)
3015 3036 return (NULL);
3016 3037
3017 3038 devid_free_nmlist(list);
3018 3039
3019 3040 return (path);
3020 3041 }
3021 3042
3022 3043 /*
3023 3044 * Convert from a path to a devid string.
3024 3045 */
3025 3046 static char *
3026 3047 path_to_devid(const char *path)
3027 3048 {
3028 3049 int fd;
3029 3050 ddi_devid_t devid;
3030 3051 char *minor, *ret;
3031 3052
3032 3053 if ((fd = open(path, O_RDONLY)) < 0)
3033 3054 return (NULL);
3034 3055
3035 3056 minor = NULL;
3036 3057 ret = NULL;
3037 3058 if (devid_get(fd, &devid) == 0) {
3038 3059 if (devid_get_minor_name(fd, &minor) == 0)
3039 3060 ret = devid_str_encode(devid, minor);
3040 3061 if (minor != NULL)
3041 3062 devid_str_free(minor);
3042 3063 devid_free(devid);
3043 3064 }
3044 3065 (void) close(fd);
3045 3066
3046 3067 return (ret);
3047 3068 }
3048 3069
3049 3070 /*
3050 3071 * Issue the necessary ioctl() to update the stored path value for the vdev. We
3051 3072 * ignore any failure here, since a common case is for an unprivileged user to
3052 3073 * type 'zpool status', and we'll display the correct information anyway.
3053 3074 */
3054 3075 static void
3055 3076 set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
3056 3077 {
3057 3078 zfs_cmd_t zc = { 0 };
3058 3079
3059 3080 (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3060 3081 (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
3061 3082 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
3062 3083 &zc.zc_guid) == 0);
3063 3084
3064 3085 (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
3065 3086 }
3066 3087
3067 3088 /*
3068 3089 * Given a vdev, return the name to display in iostat. If the vdev has a path,
3069 3090 * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
3070 3091 * We also check if this is a whole disk, in which case we strip off the
3071 3092 * trailing 's0' slice name.
3072 3093 *
3073 3094 * This routine is also responsible for identifying when disks have been
3074 3095 * reconfigured in a new location. The kernel will have opened the device by
3075 3096 * devid, but the path will still refer to the old location. To catch this, we
3076 3097 * first do a path -> devid translation (which is fast for the common case). If
3077 3098 * the devid matches, we're done. If not, we do a reverse devid -> path
3078 3099 * translation and issue the appropriate ioctl() to update the path of the vdev.
3079 3100 * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
3080 3101 * of these checks.
3081 3102 */
3082 3103 char *
3083 3104 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
3084 3105 boolean_t verbose)
3085 3106 {
3086 3107 char *path, *devid;
3087 3108 uint64_t value;
3088 3109 char buf[64];
3089 3110 vdev_stat_t *vs;
3090 3111 uint_t vsc;
3091 3112
3092 3113 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
3093 3114 &value) == 0) {
3094 3115 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
3095 3116 &value) == 0);
3096 3117 (void) snprintf(buf, sizeof (buf), "%llu",
3097 3118 (u_longlong_t)value);
3098 3119 path = buf;
3099 3120 } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
3100 3121
3101 3122 /*
3102 3123 * If the device is dead (faulted, offline, etc) then don't
3103 3124 * bother opening it. Otherwise we may be forcing the user to
3104 3125 * open a misbehaving device, which can have undesirable
3105 3126 * effects.
3106 3127 */
3107 3128 if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
3108 3129 (uint64_t **)&vs, &vsc) != 0 ||
3109 3130 vs->vs_state >= VDEV_STATE_DEGRADED) &&
3110 3131 zhp != NULL &&
3111 3132 nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
3112 3133 /*
3113 3134 * Determine if the current path is correct.
3114 3135 */
3115 3136 char *newdevid = path_to_devid(path);
3116 3137
3117 3138 if (newdevid == NULL ||
3118 3139 strcmp(devid, newdevid) != 0) {
3119 3140 char *newpath;
3120 3141
3121 3142 if ((newpath = devid_to_path(devid)) != NULL) {
3122 3143 /*
3123 3144 * Update the path appropriately.
3124 3145 */
3125 3146 set_path(zhp, nv, newpath);
3126 3147 if (nvlist_add_string(nv,
3127 3148 ZPOOL_CONFIG_PATH, newpath) == 0)
3128 3149 verify(nvlist_lookup_string(nv,
3129 3150 ZPOOL_CONFIG_PATH,
3130 3151 &path) == 0);
3131 3152 free(newpath);
3132 3153 }
3133 3154 }
3134 3155
3135 3156 if (newdevid)
3136 3157 devid_str_free(newdevid);
3137 3158 }
3138 3159
3139 3160 if (strncmp(path, "/dev/dsk/", 9) == 0)
3140 3161 path += 9;
3141 3162
3142 3163 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
3143 3164 &value) == 0 && value) {
3144 3165 int pathlen = strlen(path);
3145 3166 char *tmp = zfs_strdup(hdl, path);
3146 3167
3147 3168 /*
3148 3169 * If it starts with c#, and ends with "s0", chop
3149 3170 * the "s0" off, or if it ends with "s0/old", remove
3150 3171 * the "s0" from the middle.
3151 3172 */
3152 3173 if (CTD_CHECK(tmp)) {
3153 3174 if (strcmp(&tmp[pathlen - 2], "s0") == 0) {
3154 3175 tmp[pathlen - 2] = '\0';
3155 3176 } else if (pathlen > 6 &&
3156 3177 strcmp(&tmp[pathlen - 6], "s0/old") == 0) {
3157 3178 (void) strcpy(&tmp[pathlen - 6],
3158 3179 "/old");
3159 3180 }
3160 3181 }
3161 3182 return (tmp);
3162 3183 }
3163 3184 } else {
3164 3185 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
3165 3186
3166 3187 /*
3167 3188 * If it's a raidz device, we need to stick in the parity level.
3168 3189 */
3169 3190 if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
3170 3191 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
3171 3192 &value) == 0);
3172 3193 (void) snprintf(buf, sizeof (buf), "%s%llu", path,
3173 3194 (u_longlong_t)value);
3174 3195 path = buf;
3175 3196 }
3176 3197
3177 3198 /*
3178 3199 * We identify each top-level vdev by using a <type-id>
3179 3200 * naming convention.
3180 3201 */
3181 3202 if (verbose) {
3182 3203 uint64_t id;
3183 3204
3184 3205 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
3185 3206 &id) == 0);
3186 3207 (void) snprintf(buf, sizeof (buf), "%s-%llu", path,
3187 3208 (u_longlong_t)id);
3188 3209 path = buf;
3189 3210 }
3190 3211 }
3191 3212
3192 3213 return (zfs_strdup(hdl, path));
3193 3214 }
3194 3215
3195 3216 static int
3196 3217 zbookmark_compare(const void *a, const void *b)
3197 3218 {
3198 3219 return (memcmp(a, b, sizeof (zbookmark_t)));
3199 3220 }
3200 3221
3201 3222 /*
3202 3223 * Retrieve the persistent error log, uniquify the members, and return to the
3203 3224 * caller.
3204 3225 */
3205 3226 int
3206 3227 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
3207 3228 {
3208 3229 zfs_cmd_t zc = { 0 };
3209 3230 uint64_t count;
3210 3231 zbookmark_t *zb = NULL;
3211 3232 int i;
3212 3233
3213 3234 /*
3214 3235 * Retrieve the raw error list from the kernel. If the number of errors
3215 3236 * has increased, allocate more space and continue until we get the
3216 3237 * entire list.
3217 3238 */
3218 3239 verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
3219 3240 &count) == 0);
3220 3241 if (count == 0)
3221 3242 return (0);
3222 3243 if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
3223 3244 count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
3224 3245 return (-1);
3225 3246 zc.zc_nvlist_dst_size = count;
3226 3247 (void) strcpy(zc.zc_name, zhp->zpool_name);
3227 3248 for (;;) {
3228 3249 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
3229 3250 &zc) != 0) {
3230 3251 free((void *)(uintptr_t)zc.zc_nvlist_dst);
3231 3252 if (errno == ENOMEM) {
3232 3253 count = zc.zc_nvlist_dst_size;
3233 3254 if ((zc.zc_nvlist_dst = (uintptr_t)
3234 3255 zfs_alloc(zhp->zpool_hdl, count *
3235 3256 sizeof (zbookmark_t))) == (uintptr_t)NULL)
3236 3257 return (-1);
3237 3258 } else {
3238 3259 return (-1);
3239 3260 }
3240 3261 } else {
3241 3262 break;
3242 3263 }
3243 3264 }
3244 3265
3245 3266 /*
3246 3267 * Sort the resulting bookmarks. This is a little confusing due to the
3247 3268 * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last
3248 3269 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
3249 3270 * _not_ copied as part of the process. So we point the start of our
3250 3271 * array appropriate and decrement the total number of elements.
3251 3272 */
3252 3273 zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
3253 3274 zc.zc_nvlist_dst_size;
3254 3275 count -= zc.zc_nvlist_dst_size;
3255 3276
3256 3277 qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
3257 3278
3258 3279 verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
3259 3280
3260 3281 /*
3261 3282 * Fill in the nverrlistp with nvlist's of dataset and object numbers.
3262 3283 */
3263 3284 for (i = 0; i < count; i++) {
3264 3285 nvlist_t *nv;
3265 3286
3266 3287 /* ignoring zb_blkid and zb_level for now */
3267 3288 if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
3268 3289 zb[i-1].zb_object == zb[i].zb_object)
3269 3290 continue;
3270 3291
3271 3292 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
3272 3293 goto nomem;
3273 3294 if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
3274 3295 zb[i].zb_objset) != 0) {
3275 3296 nvlist_free(nv);
3276 3297 goto nomem;
3277 3298 }
3278 3299 if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
3279 3300 zb[i].zb_object) != 0) {
3280 3301 nvlist_free(nv);
3281 3302 goto nomem;
3282 3303 }
3283 3304 if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
3284 3305 nvlist_free(nv);
3285 3306 goto nomem;
3286 3307 }
3287 3308 nvlist_free(nv);
3288 3309 }
3289 3310
3290 3311 free((void *)(uintptr_t)zc.zc_nvlist_dst);
3291 3312 return (0);
3292 3313
3293 3314 nomem:
3294 3315 free((void *)(uintptr_t)zc.zc_nvlist_dst);
3295 3316 return (no_memory(zhp->zpool_hdl));
3296 3317 }
3297 3318
3298 3319 /*
3299 3320 * Upgrade a ZFS pool to the latest on-disk version.
3300 3321 */
3301 3322 int
3302 3323 zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
3303 3324 {
3304 3325 zfs_cmd_t zc = { 0 };
3305 3326 libzfs_handle_t *hdl = zhp->zpool_hdl;
3306 3327
3307 3328 (void) strcpy(zc.zc_name, zhp->zpool_name);
3308 3329 zc.zc_cookie = new_version;
3309 3330
3310 3331 if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
3311 3332 return (zpool_standard_error_fmt(hdl, errno,
3312 3333 dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
3313 3334 zhp->zpool_name));
3314 3335 return (0);
3315 3336 }
3316 3337
3317 3338 void
3318 3339 zpool_set_history_str(const char *subcommand, int argc, char **argv,
3319 3340 char *history_str)
3320 3341 {
3321 3342 int i;
3322 3343
3323 3344 (void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
3324 3345 for (i = 1; i < argc; i++) {
3325 3346 if (strlen(history_str) + 1 + strlen(argv[i]) >
3326 3347 HIS_MAX_RECORD_LEN)
3327 3348 break;
3328 3349 (void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN);
3329 3350 (void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
3330 3351 }
3331 3352 }
3332 3353
3333 3354 /*
3334 3355 * Stage command history for logging.
3335 3356 */
3336 3357 int
3337 3358 zpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
3338 3359 {
3339 3360 if (history_str == NULL)
3340 3361 return (EINVAL);
3341 3362
3342 3363 if (strlen(history_str) > HIS_MAX_RECORD_LEN)
3343 3364 return (EINVAL);
3344 3365
3345 3366 if (hdl->libzfs_log_str != NULL)
3346 3367 free(hdl->libzfs_log_str);
3347 3368
3348 3369 if ((hdl->libzfs_log_str = strdup(history_str)) == NULL)
3349 3370 return (no_memory(hdl));
3350 3371
3351 3372 return (0);
3352 3373 }
3353 3374
3354 3375 /*
3355 3376 * Perform ioctl to get some command history of a pool.
3356 3377 *
3357 3378 * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the
3358 3379 * logical offset of the history buffer to start reading from.
3359 3380 *
3360 3381 * Upon return, 'off' is the next logical offset to read from and
3361 3382 * 'len' is the actual amount of bytes read into 'buf'.
3362 3383 */
3363 3384 static int
3364 3385 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
3365 3386 {
3366 3387 zfs_cmd_t zc = { 0 };
3367 3388 libzfs_handle_t *hdl = zhp->zpool_hdl;
3368 3389
3369 3390 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3370 3391
3371 3392 zc.zc_history = (uint64_t)(uintptr_t)buf;
3372 3393 zc.zc_history_len = *len;
3373 3394 zc.zc_history_offset = *off;
3374 3395
3375 3396 if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
3376 3397 switch (errno) {
3377 3398 case EPERM:
3378 3399 return (zfs_error_fmt(hdl, EZFS_PERM,
3379 3400 dgettext(TEXT_DOMAIN,
3380 3401 "cannot show history for pool '%s'"),
3381 3402 zhp->zpool_name));
3382 3403 case ENOENT:
3383 3404 return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
3384 3405 dgettext(TEXT_DOMAIN, "cannot get history for pool "
3385 3406 "'%s'"), zhp->zpool_name));
3386 3407 case ENOTSUP:
3387 3408 return (zfs_error_fmt(hdl, EZFS_BADVERSION,
3388 3409 dgettext(TEXT_DOMAIN, "cannot get history for pool "
3389 3410 "'%s', pool must be upgraded"), zhp->zpool_name));
3390 3411 default:
3391 3412 return (zpool_standard_error_fmt(hdl, errno,
3392 3413 dgettext(TEXT_DOMAIN,
3393 3414 "cannot get history for '%s'"), zhp->zpool_name));
3394 3415 }
3395 3416 }
3396 3417
3397 3418 *len = zc.zc_history_len;
3398 3419 *off = zc.zc_history_offset;
3399 3420
3400 3421 return (0);
3401 3422 }
3402 3423
3403 3424 /*
3404 3425 * Process the buffer of nvlists, unpacking and storing each nvlist record
3405 3426 * into 'records'. 'leftover' is set to the number of bytes that weren't
3406 3427 * processed as there wasn't a complete record.
3407 3428 */
3408 3429 int
3409 3430 zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
3410 3431 nvlist_t ***records, uint_t *numrecords)
3411 3432 {
3412 3433 uint64_t reclen;
3413 3434 nvlist_t *nv;
3414 3435 int i;
3415 3436
3416 3437 while (bytes_read > sizeof (reclen)) {
3417 3438
3418 3439 /* get length of packed record (stored as little endian) */
3419 3440 for (i = 0, reclen = 0; i < sizeof (reclen); i++)
3420 3441 reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
3421 3442
3422 3443 if (bytes_read < sizeof (reclen) + reclen)
3423 3444 break;
3424 3445
3425 3446 /* unpack record */
3426 3447 if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
3427 3448 return (ENOMEM);
3428 3449 bytes_read -= sizeof (reclen) + reclen;
3429 3450 buf += sizeof (reclen) + reclen;
3430 3451
3431 3452 /* add record to nvlist array */
3432 3453 (*numrecords)++;
3433 3454 if (ISP2(*numrecords + 1)) {
3434 3455 *records = realloc(*records,
3435 3456 *numrecords * 2 * sizeof (nvlist_t *));
3436 3457 }
3437 3458 (*records)[*numrecords - 1] = nv;
3438 3459 }
3439 3460
3440 3461 *leftover = bytes_read;
3441 3462 return (0);
3442 3463 }
3443 3464
3444 3465 #define HIS_BUF_LEN (128*1024)
3445 3466
3446 3467 /*
3447 3468 * Retrieve the command history of a pool.
3448 3469 */
3449 3470 int
3450 3471 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
3451 3472 {
3452 3473 char buf[HIS_BUF_LEN];
3453 3474 uint64_t off = 0;
3454 3475 nvlist_t **records = NULL;
3455 3476 uint_t numrecords = 0;
3456 3477 int err, i;
3457 3478
3458 3479 do {
3459 3480 uint64_t bytes_read = sizeof (buf);
3460 3481 uint64_t leftover;
3461 3482
3462 3483 if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
3463 3484 break;
3464 3485
3465 3486 /* if nothing else was read in, we're at EOF, just return */
3466 3487 if (!bytes_read)
3467 3488 break;
3468 3489
3469 3490 if ((err = zpool_history_unpack(buf, bytes_read,
3470 3491 &leftover, &records, &numrecords)) != 0)
3471 3492 break;
3472 3493 off -= leftover;
3473 3494
3474 3495 /* CONSTCOND */
3475 3496 } while (1);
3476 3497
3477 3498 if (!err) {
3478 3499 verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
3479 3500 verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
3480 3501 records, numrecords) == 0);
3481 3502 }
3482 3503 for (i = 0; i < numrecords; i++)
3483 3504 nvlist_free(records[i]);
3484 3505 free(records);
3485 3506
3486 3507 return (err);
3487 3508 }
3488 3509
3489 3510 void
3490 3511 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
3491 3512 char *pathname, size_t len)
3492 3513 {
3493 3514 zfs_cmd_t zc = { 0 };
3494 3515 boolean_t mounted = B_FALSE;
3495 3516 char *mntpnt = NULL;
3496 3517 char dsname[MAXNAMELEN];
3497 3518
3498 3519 if (dsobj == 0) {
3499 3520 /* special case for the MOS */
3500 3521 (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
3501 3522 return;
3502 3523 }
3503 3524
3504 3525 /* get the dataset's name */
3505 3526 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3506 3527 zc.zc_obj = dsobj;
3507 3528 if (ioctl(zhp->zpool_hdl->libzfs_fd,
3508 3529 ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
3509 3530 /* just write out a path of two object numbers */
3510 3531 (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
3511 3532 dsobj, obj);
3512 3533 return;
3513 3534 }
3514 3535 (void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
3515 3536
3516 3537 /* find out if the dataset is mounted */
3517 3538 mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt);
3518 3539
3519 3540 /* get the corrupted object's path */
3520 3541 (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
3521 3542 zc.zc_obj = obj;
3522 3543 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
3523 3544 &zc) == 0) {
3524 3545 if (mounted) {
3525 3546 (void) snprintf(pathname, len, "%s%s", mntpnt,
3526 3547 zc.zc_value);
3527 3548 } else {
3528 3549 (void) snprintf(pathname, len, "%s:%s",
3529 3550 dsname, zc.zc_value);
3530 3551 }
3531 3552 } else {
3532 3553 (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
3533 3554 }
3534 3555 free(mntpnt);
3535 3556 }
3536 3557
3537 3558 /*
3538 3559 * Read the EFI label from the config, if a label does not exist then
3539 3560 * pass back the error to the caller. If the caller has passed a non-NULL
3540 3561 * diskaddr argument then we set it to the starting address of the EFI
3541 3562 * partition.
3542 3563 */
3543 3564 static int
3544 3565 read_efi_label(nvlist_t *config, diskaddr_t *sb)
3545 3566 {
3546 3567 char *path;
3547 3568 int fd;
3548 3569 char diskname[MAXPATHLEN];
3549 3570 int err = -1;
3550 3571
3551 3572 if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
3552 3573 return (err);
3553 3574
3554 3575 (void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT,
3555 3576 strrchr(path, '/'));
3556 3577 if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) {
3557 3578 struct dk_gpt *vtoc;
3558 3579
3559 3580 if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) {
3560 3581 if (sb != NULL)
3561 3582 *sb = vtoc->efi_parts[0].p_start;
3562 3583 efi_free(vtoc);
3563 3584 }
3564 3585 (void) close(fd);
3565 3586 }
3566 3587 return (err);
3567 3588 }
3568 3589
3569 3590 /*
3570 3591 * determine where a partition starts on a disk in the current
3571 3592 * configuration
3572 3593 */
3573 3594 static diskaddr_t
3574 3595 find_start_block(nvlist_t *config)
3575 3596 {
3576 3597 nvlist_t **child;
3577 3598 uint_t c, children;
3578 3599 diskaddr_t sb = MAXOFFSET_T;
3579 3600 uint64_t wholedisk;
3580 3601
3581 3602 if (nvlist_lookup_nvlist_array(config,
3582 3603 ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) {
3583 3604 if (nvlist_lookup_uint64(config,
3584 3605 ZPOOL_CONFIG_WHOLE_DISK,
3585 3606 &wholedisk) != 0 || !wholedisk) {
3586 3607 return (MAXOFFSET_T);
3587 3608 }
3588 3609 if (read_efi_label(config, &sb) < 0)
3589 3610 sb = MAXOFFSET_T;
3590 3611 return (sb);
3591 3612 }
3592 3613
3593 3614 for (c = 0; c < children; c++) {
3594 3615 sb = find_start_block(child[c]);
3595 3616 if (sb != MAXOFFSET_T) {
3596 3617 return (sb);
3597 3618 }
3598 3619 }
3599 3620 return (MAXOFFSET_T);
3600 3621 }
3601 3622
3602 3623 /*
3603 3624 * Label an individual disk. The name provided is the short name,
3604 3625 * stripped of any leading /dev path.
3605 3626 */
3606 3627 int
3607 3628 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
3608 3629 {
3609 3630 char path[MAXPATHLEN];
3610 3631 struct dk_gpt *vtoc;
3611 3632 int fd;
3612 3633 size_t resv = EFI_MIN_RESV_SIZE;
3613 3634 uint64_t slice_size;
3614 3635 diskaddr_t start_block;
3615 3636 char errbuf[1024];
3616 3637
3617 3638 /* prepare an error message just in case */
3618 3639 (void) snprintf(errbuf, sizeof (errbuf),
3619 3640 dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
3620 3641
3621 3642 if (zhp) {
3622 3643 nvlist_t *nvroot;
3623 3644
3624 3645 if (pool_is_bootable(zhp)) {
3625 3646 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3626 3647 "EFI labeled devices are not supported on root "
3627 3648 "pools."));
3628 3649 return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
3629 3650 }
3630 3651
3631 3652 verify(nvlist_lookup_nvlist(zhp->zpool_config,
3632 3653 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
3633 3654
3634 3655 if (zhp->zpool_start_block == 0)
3635 3656 start_block = find_start_block(nvroot);
3636 3657 else
3637 3658 start_block = zhp->zpool_start_block;
3638 3659 zhp->zpool_start_block = start_block;
3639 3660 } else {
3640 3661 /* new pool */
3641 3662 start_block = NEW_START_BLOCK;
3642 3663 }
3643 3664
3644 3665 (void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
3645 3666 BACKUP_SLICE);
3646 3667
3647 3668 if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
3648 3669 /*
3649 3670 * This shouldn't happen. We've long since verified that this
3650 3671 * is a valid device.
3651 3672 */
3652 3673 zfs_error_aux(hdl,
3653 3674 dgettext(TEXT_DOMAIN, "unable to open device"));
3654 3675 return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
3655 3676 }
3656 3677
3657 3678 if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
3658 3679 /*
3659 3680 * The only way this can fail is if we run out of memory, or we
3660 3681 * were unable to read the disk's capacity
3661 3682 */
3662 3683 if (errno == ENOMEM)
3663 3684 (void) no_memory(hdl);
3664 3685
3665 3686 (void) close(fd);
3666 3687 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3667 3688 "unable to read disk capacity"), name);
3668 3689
3669 3690 return (zfs_error(hdl, EZFS_NOCAP, errbuf));
3670 3691 }
3671 3692
3672 3693 slice_size = vtoc->efi_last_u_lba + 1;
3673 3694 slice_size -= EFI_MIN_RESV_SIZE;
3674 3695 if (start_block == MAXOFFSET_T)
3675 3696 start_block = NEW_START_BLOCK;
3676 3697 slice_size -= start_block;
3677 3698
3678 3699 vtoc->efi_parts[0].p_start = start_block;
3679 3700 vtoc->efi_parts[0].p_size = slice_size;
3680 3701
3681 3702 /*
3682 3703 * Why we use V_USR: V_BACKUP confuses users, and is considered
3683 3704 * disposable by some EFI utilities (since EFI doesn't have a backup
3684 3705 * slice). V_UNASSIGNED is supposed to be used only for zero size
3685 3706 * partitions, and efi_write() will fail if we use it. V_ROOT, V_BOOT,
3686 3707 * etc. were all pretty specific. V_USR is as close to reality as we
3687 3708 * can get, in the absence of V_OTHER.
3688 3709 */
3689 3710 vtoc->efi_parts[0].p_tag = V_USR;
3690 3711 (void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
3691 3712
3692 3713 vtoc->efi_parts[8].p_start = slice_size + start_block;
3693 3714 vtoc->efi_parts[8].p_size = resv;
3694 3715 vtoc->efi_parts[8].p_tag = V_RESERVED;
3695 3716
3696 3717 if (efi_write(fd, vtoc) != 0) {
3697 3718 /*
3698 3719 * Some block drivers (like pcata) may not support EFI
3699 3720 * GPT labels. Print out a helpful error message dir-
3700 3721 * ecting the user to manually label the disk and give
3701 3722 * a specific slice.
3702 3723 */
3703 3724 (void) close(fd);
3704 3725 efi_free(vtoc);
3705 3726
3706 3727 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3707 3728 "try using fdisk(1M) and then provide a specific slice"));
3708 3729 return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
3709 3730 }
3710 3731
3711 3732 (void) close(fd);
3712 3733 efi_free(vtoc);
3713 3734 return (0);
3714 3735 }
3715 3736
3716 3737 static boolean_t
3717 3738 supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf)
3718 3739 {
3719 3740 char *type;
3720 3741 nvlist_t **child;
3721 3742 uint_t children, c;
3722 3743
3723 3744 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0);
3724 3745 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
3725 3746 strcmp(type, VDEV_TYPE_FILE) == 0 ||
3726 3747 strcmp(type, VDEV_TYPE_LOG) == 0 ||
3727 3748 strcmp(type, VDEV_TYPE_HOLE) == 0 ||
3728 3749 strcmp(type, VDEV_TYPE_MISSING) == 0) {
3729 3750 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3730 3751 "vdev type '%s' is not supported"), type);
3731 3752 (void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf);
3732 3753 return (B_FALSE);
3733 3754 }
3734 3755 if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
3735 3756 &child, &children) == 0) {
3736 3757 for (c = 0; c < children; c++) {
3737 3758 if (!supported_dump_vdev_type(hdl, child[c], errbuf))
3738 3759 return (B_FALSE);
3739 3760 }
3740 3761 }
3741 3762 return (B_TRUE);
3742 3763 }
3743 3764
3744 3765 /*
3745 3766 * check if this zvol is allowable for use as a dump device; zero if
3746 3767 * it is, > 0 if it isn't, < 0 if it isn't a zvol
3747 3768 */
3748 3769 int
3749 3770 zvol_check_dump_config(char *arg)
3750 3771 {
3751 3772 zpool_handle_t *zhp = NULL;
3752 3773 nvlist_t *config, *nvroot;
3753 3774 char *p, *volname;
3754 3775 nvlist_t **top;
3755 3776 uint_t toplevels;
3756 3777 libzfs_handle_t *hdl;
3757 3778 char errbuf[1024];
3758 3779 char poolname[ZPOOL_MAXNAMELEN];
3759 3780 int pathlen = strlen(ZVOL_FULL_DEV_DIR);
3760 3781 int ret = 1;
3761 3782
3762 3783 if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) {
3763 3784 return (-1);
3764 3785 }
3765 3786
3766 3787 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3767 3788 "dump is not supported on device '%s'"), arg);
3768 3789
3769 3790 if ((hdl = libzfs_init()) == NULL)
3770 3791 return (1);
3771 3792 libzfs_print_on_error(hdl, B_TRUE);
3772 3793
3773 3794 volname = arg + pathlen;
3774 3795
3775 3796 /* check the configuration of the pool */
3776 3797 if ((p = strchr(volname, '/')) == NULL) {
3777 3798 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3778 3799 "malformed dataset name"));
3779 3800 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
3780 3801 return (1);
3781 3802 } else if (p - volname >= ZFS_MAXNAMELEN) {
3782 3803 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3783 3804 "dataset name is too long"));
3784 3805 (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf);
3785 3806 return (1);
3786 3807 } else {
3787 3808 (void) strncpy(poolname, volname, p - volname);
3788 3809 poolname[p - volname] = '\0';
3789 3810 }
3790 3811
3791 3812 if ((zhp = zpool_open(hdl, poolname)) == NULL) {
3792 3813 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3793 3814 "could not open pool '%s'"), poolname);
3794 3815 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
3795 3816 goto out;
3796 3817 }
3797 3818 config = zpool_get_config(zhp, NULL);
3798 3819 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3799 3820 &nvroot) != 0) {
3800 3821 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3801 3822 "could not obtain vdev configuration for '%s'"), poolname);
3802 3823 (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
3803 3824 goto out;
3804 3825 }
3805 3826
3806 3827 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
3807 3828 &top, &toplevels) == 0);
3808 3829 if (toplevels != 1) {
3809 3830 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3810 3831 "'%s' has multiple top level vdevs"), poolname);
3811 3832 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf);
3812 3833 goto out;
3813 3834 }
3814 3835
3815 3836 if (!supported_dump_vdev_type(hdl, top[0], errbuf)) {
3816 3837 goto out;
3817 3838 }
3818 3839 ret = 0;
3819 3840
3820 3841 out:
3821 3842 if (zhp)
3822 3843 zpool_close(zhp);
3823 3844 libzfs_fini(hdl);
3824 3845 return (ret);
3825 3846 }
|
↓ open down ↓ |
3270 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX