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