1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <assert.h> 28 #include <ctype.h> 29 #include <errno.h> 30 #include <libdevinfo.h> 31 #include <libintl.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <strings.h> 35 #include <unistd.h> 36 #include <stddef.h> 37 #include <fcntl.h> 38 #include <sys/mount.h> 39 #include <sys/mntent.h> 40 #include <sys/mnttab.h> 41 #include <sys/avl.h> 42 #include <stddef.h> 43 44 #include <libzfs.h> 45 46 #include "zfs_namecheck.h" 47 #include "zfs_prop.h" 48 #include "libzfs_impl.h" 49 50 #include <fletcher.c> /* XXX */ 51 52 static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t, 53 int, avl_tree_t *, char **); 54 55 /* 56 * Routines for dealing with the AVL tree of fs-nvlists 57 */ 58 typedef struct fsavl_node { 59 avl_node_t fn_node; 60 nvlist_t *fn_nvfs; 61 char *fn_snapname; 62 uint64_t fn_guid; 63 } fsavl_node_t; 64 65 static int 66 fsavl_compare(const void *arg1, const void *arg2) 67 { 68 const fsavl_node_t *fn1 = arg1; 69 const fsavl_node_t *fn2 = arg2; 70 71 if (fn1->fn_guid > fn2->fn_guid) 72 return (+1); 73 else if (fn1->fn_guid < fn2->fn_guid) 74 return (-1); 75 else 76 return (0); 77 } 78 79 /* 80 * Given the GUID of a snapshot, find its containing filesystem and 81 * (optionally) name. 82 */ 83 static nvlist_t * 84 fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname) 85 { 86 fsavl_node_t fn_find; 87 fsavl_node_t *fn; 88 89 fn_find.fn_guid = snapguid; 90 91 fn = avl_find(avl, &fn_find, NULL); 92 if (fn) { 93 if (snapname) 94 *snapname = fn->fn_snapname; 95 return (fn->fn_nvfs); 96 } 97 return (NULL); 98 } 99 100 static void 101 fsavl_destroy(avl_tree_t *avl) 102 { 103 fsavl_node_t *fn; 104 void *cookie; 105 106 if (avl == NULL) 107 return; 108 109 cookie = NULL; 110 while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL) 111 free(fn); 112 avl_destroy(avl); 113 free(avl); 114 } 115 116 static avl_tree_t * 117 fsavl_create(nvlist_t *fss) 118 { 119 avl_tree_t *fsavl; 120 nvpair_t *fselem = NULL; 121 122 if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL) 123 return (NULL); 124 125 avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t), 126 offsetof(fsavl_node_t, fn_node)); 127 128 while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) { 129 nvlist_t *nvfs, *snaps; 130 nvpair_t *snapelem = NULL; 131 132 VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs)); 133 VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps)); 134 135 while ((snapelem = 136 nvlist_next_nvpair(snaps, snapelem)) != NULL) { 137 fsavl_node_t *fn; 138 uint64_t guid; 139 140 VERIFY(0 == nvpair_value_uint64(snapelem, &guid)); 141 if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) { 142 fsavl_destroy(fsavl); 143 return (NULL); 144 } 145 fn->fn_nvfs = nvfs; 146 fn->fn_snapname = nvpair_name(snapelem); 147 fn->fn_guid = guid; 148 149 /* 150 * Note: if there are multiple snaps with the 151 * same GUID, we ignore all but one. 152 */ 153 if (avl_find(fsavl, fn, NULL) == NULL) 154 avl_add(fsavl, fn); 155 else 156 free(fn); 157 } 158 } 159 160 return (fsavl); 161 } 162 163 /* 164 * Routines for dealing with the giant nvlist of fs-nvlists, etc. 165 */ 166 typedef struct send_data { 167 uint64_t parent_fromsnap_guid; 168 nvlist_t *parent_snaps; 169 nvlist_t *fss; 170 nvlist_t *snapprops; 171 const char *fromsnap; 172 const char *tosnap; 173 174 /* 175 * The header nvlist is of the following format: 176 * { 177 * "tosnap" -> string 178 * "fromsnap" -> string (if incremental) 179 * "fss" -> { 180 * id -> { 181 * 182 * "name" -> string (full name; for debugging) 183 * "parentfromsnap" -> number (guid of fromsnap in parent) 184 * 185 * "props" -> { name -> value (only if set here) } 186 * "snaps" -> { name (lastname) -> number (guid) } 187 * "snapprops" -> { name (lastname) -> { name -> value } } 188 * 189 * "origin" -> number (guid) (if clone) 190 * "sent" -> boolean (not on-disk) 191 * } 192 * } 193 * } 194 * 195 */ 196 } send_data_t; 197 198 static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv); 199 200 static int 201 send_iterate_snap(zfs_handle_t *zhp, void *arg) 202 { 203 send_data_t *sd = arg; 204 uint64_t guid = zhp->zfs_dmustats.dds_guid; 205 char *snapname; 206 nvlist_t *nv; 207 208 snapname = strrchr(zhp->zfs_name, '@')+1; 209 210 VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid)); 211 /* 212 * NB: if there is no fromsnap here (it's a newly created fs in 213 * an incremental replication), we will substitute the tosnap. 214 */ 215 if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) || 216 (sd->parent_fromsnap_guid == 0 && sd->tosnap && 217 strcmp(snapname, sd->tosnap) == 0)) { 218 sd->parent_fromsnap_guid = guid; 219 } 220 221 VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0)); 222 send_iterate_prop(zhp, nv); 223 VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv)); 224 nvlist_free(nv); 225 226 zfs_close(zhp); 227 return (0); 228 } 229 230 static void 231 send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv) 232 { 233 nvpair_t *elem = NULL; 234 235 while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) { 236 char *propname = nvpair_name(elem); 237 zfs_prop_t prop = zfs_name_to_prop(propname); 238 nvlist_t *propnv; 239 240 if (!zfs_prop_user(propname) && zfs_prop_readonly(prop)) 241 continue; 242 243 verify(nvpair_value_nvlist(elem, &propnv) == 0); 244 if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION) { 245 /* these guys are modifyable, but have no source */ 246 uint64_t value; 247 verify(nvlist_lookup_uint64(propnv, 248 ZPROP_VALUE, &value) == 0); 249 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) 250 continue; 251 } else { 252 char *source; 253 if (nvlist_lookup_string(propnv, 254 ZPROP_SOURCE, &source) != 0) 255 continue; 256 if (strcmp(source, zhp->zfs_name) != 0) 257 continue; 258 } 259 260 if (zfs_prop_user(propname) || 261 zfs_prop_get_type(prop) == PROP_TYPE_STRING) { 262 char *value; 263 verify(nvlist_lookup_string(propnv, 264 ZPROP_VALUE, &value) == 0); 265 VERIFY(0 == nvlist_add_string(nv, propname, value)); 266 } else { 267 uint64_t value; 268 verify(nvlist_lookup_uint64(propnv, 269 ZPROP_VALUE, &value) == 0); 270 VERIFY(0 == nvlist_add_uint64(nv, propname, value)); 271 } 272 } 273 } 274 275 static int 276 send_iterate_fs(zfs_handle_t *zhp, void *arg) 277 { 278 send_data_t *sd = arg; 279 nvlist_t *nvfs, *nv; 280 int rv; 281 uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid; 282 uint64_t guid = zhp->zfs_dmustats.dds_guid; 283 char guidstring[64]; 284 285 VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0)); 286 VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name)); 287 VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap", 288 sd->parent_fromsnap_guid)); 289 290 if (zhp->zfs_dmustats.dds_origin[0]) { 291 zfs_handle_t *origin = zfs_open(zhp->zfs_hdl, 292 zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT); 293 if (origin == NULL) 294 return (-1); 295 VERIFY(0 == nvlist_add_uint64(nvfs, "origin", 296 origin->zfs_dmustats.dds_guid)); 297 } 298 299 /* iterate over props */ 300 VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0)); 301 send_iterate_prop(zhp, nv); 302 VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv)); 303 nvlist_free(nv); 304 305 /* iterate over snaps, and set sd->parent_fromsnap_guid */ 306 sd->parent_fromsnap_guid = 0; 307 VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0)); 308 VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0)); 309 (void) zfs_iter_snapshots(zhp, send_iterate_snap, sd); 310 VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps)); 311 VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops)); 312 nvlist_free(sd->parent_snaps); 313 nvlist_free(sd->snapprops); 314 315 /* add this fs to nvlist */ 316 (void) snprintf(guidstring, sizeof (guidstring), 317 "0x%llx", (longlong_t)guid); 318 VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs)); 319 nvlist_free(nvfs); 320 321 /* iterate over children */ 322 rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd); 323 324 sd->parent_fromsnap_guid = parent_fromsnap_guid_save; 325 326 zfs_close(zhp); 327 return (rv); 328 } 329 330 static int 331 gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap, 332 const char *tosnap, nvlist_t **nvlp, avl_tree_t **avlp) 333 { 334 zfs_handle_t *zhp; 335 send_data_t sd = { 0 }; 336 int error; 337 338 zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); 339 if (zhp == NULL) 340 return (EZFS_BADTYPE); 341 342 VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0)); 343 sd.fromsnap = fromsnap; 344 sd.tosnap = tosnap; 345 346 if ((error = send_iterate_fs(zhp, &sd)) != 0) { 347 nvlist_free(sd.fss); 348 if (avlp != NULL) 349 *avlp = NULL; 350 *nvlp = NULL; 351 return (error); 352 } 353 354 if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) { 355 nvlist_free(sd.fss); 356 *nvlp = NULL; 357 return (EZFS_NOMEM); 358 } 359 360 *nvlp = sd.fss; 361 return (0); 362 } 363 364 /* 365 * Routines for dealing with the sorted snapshot functionality 366 */ 367 typedef struct zfs_node { 368 zfs_handle_t *zn_handle; 369 avl_node_t zn_avlnode; 370 } zfs_node_t; 371 372 static int 373 zfs_sort_snaps(zfs_handle_t *zhp, void *data) 374 { 375 avl_tree_t *avl = data; 376 zfs_node_t *node = zfs_alloc(zhp->zfs_hdl, sizeof (zfs_node_t)); 377 378 node->zn_handle = zhp; 379 avl_add(avl, node); 380 return (0); 381 } 382 383 /* ARGSUSED */ 384 static int 385 zfs_snapshot_compare(const void *larg, const void *rarg) 386 { 387 zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle; 388 zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle; 389 uint64_t lcreate, rcreate; 390 391 /* 392 * Sort them according to creation time. We use the hidden 393 * CREATETXG property to get an absolute ordering of snapshots. 394 */ 395 lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG); 396 rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG); 397 398 if (lcreate < rcreate) 399 return (-1); 400 else if (lcreate > rcreate) 401 return (+1); 402 else 403 return (0); 404 } 405 406 static int 407 zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data) 408 { 409 int ret = 0; 410 zfs_node_t *node; 411 avl_tree_t avl; 412 void *cookie = NULL; 413 414 avl_create(&avl, zfs_snapshot_compare, 415 sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode)); 416 417 ret = zfs_iter_snapshots(zhp, zfs_sort_snaps, &avl); 418 419 for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node)) 420 ret |= callback(node->zn_handle, data); 421 422 while ((node = avl_destroy_nodes(&avl, &cookie)) != NULL) 423 free(node); 424 425 avl_destroy(&avl); 426 427 return (ret); 428 } 429 430 /* 431 * Routines specific to "zfs send" 432 */ 433 typedef struct send_dump_data { 434 /* these are all just the short snapname (the part after the @) */ 435 const char *fromsnap; 436 const char *tosnap; 437 char lastsnap[ZFS_MAXNAMELEN]; 438 boolean_t seenfrom, seento, replicate, doall, fromorigin; 439 boolean_t verbose; 440 int outfd; 441 boolean_t err; 442 nvlist_t *fss; 443 avl_tree_t *fsavl; 444 } send_dump_data_t; 445 446 /* 447 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not 448 * NULL) to the file descriptor specified by outfd. 449 */ 450 static int 451 dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin, 452 int outfd) 453 { 454 zfs_cmd_t zc = { 0 }; 455 libzfs_handle_t *hdl = zhp->zfs_hdl; 456 457 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT); 458 assert(fromsnap == NULL || fromsnap[0] == '\0' || !fromorigin); 459 460 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 461 if (fromsnap) 462 (void) strlcpy(zc.zc_value, fromsnap, sizeof (zc.zc_value)); 463 zc.zc_cookie = outfd; 464 zc.zc_obj = fromorigin; 465 466 if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SEND, &zc) != 0) { 467 char errbuf[1024]; 468 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 469 "warning: cannot send '%s'"), zhp->zfs_name); 470 471 switch (errno) { 472 473 case EXDEV: 474 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 475 "not an earlier snapshot from the same fs")); 476 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); 477 478 case ENOENT: 479 if (zfs_dataset_exists(hdl, zc.zc_name, 480 ZFS_TYPE_SNAPSHOT)) { 481 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 482 "incremental source (@%s) does not exist"), 483 zc.zc_value); 484 } 485 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 486 487 case EDQUOT: 488 case EFBIG: 489 case EIO: 490 case ENOLINK: 491 case ENOSPC: 492 case ENOSTR: 493 case ENXIO: 494 case EPIPE: 495 case ERANGE: 496 case EFAULT: 497 case EROFS: 498 zfs_error_aux(hdl, strerror(errno)); 499 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); 500 501 default: 502 return (zfs_standard_error(hdl, errno, errbuf)); 503 } 504 } 505 506 return (0); 507 } 508 509 static int 510 dump_snapshot(zfs_handle_t *zhp, void *arg) 511 { 512 send_dump_data_t *sdd = arg; 513 const char *thissnap; 514 int err; 515 516 thissnap = strchr(zhp->zfs_name, '@') + 1; 517 518 if (sdd->fromsnap && !sdd->seenfrom && 519 strcmp(sdd->fromsnap, thissnap) == 0) { 520 sdd->seenfrom = B_TRUE; 521 (void) strcpy(sdd->lastsnap, thissnap); 522 zfs_close(zhp); 523 return (0); 524 } 525 526 if (sdd->seento || !sdd->seenfrom) { 527 zfs_close(zhp); 528 return (0); 529 } 530 531 /* send it */ 532 if (sdd->verbose) { 533 (void) fprintf(stderr, "sending from @%s to %s\n", 534 sdd->lastsnap, zhp->zfs_name); 535 } 536 537 err = dump_ioctl(zhp, sdd->lastsnap, 538 sdd->lastsnap[0] == '\0' && (sdd->fromorigin || sdd->replicate), 539 sdd->outfd); 540 541 if (!sdd->seento && strcmp(sdd->tosnap, thissnap) == 0) 542 sdd->seento = B_TRUE; 543 544 (void) strcpy(sdd->lastsnap, thissnap); 545 zfs_close(zhp); 546 return (err); 547 } 548 549 static int 550 dump_filesystem(zfs_handle_t *zhp, void *arg) 551 { 552 int rv = 0; 553 send_dump_data_t *sdd = arg; 554 boolean_t missingfrom = B_FALSE; 555 zfs_cmd_t zc = { 0 }; 556 557 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s", 558 zhp->zfs_name, sdd->tosnap); 559 if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) { 560 (void) fprintf(stderr, "WARNING: " 561 "could not send %s@%s: does not exist\n", 562 zhp->zfs_name, sdd->tosnap); 563 sdd->err = B_TRUE; 564 return (0); 565 } 566 567 if (sdd->replicate && sdd->fromsnap) { 568 /* 569 * If this fs does not have fromsnap, and we're doing 570 * recursive, we need to send a full stream from the 571 * beginning (or an incremental from the origin if this 572 * is a clone). If we're doing non-recursive, then let 573 * them get the error. 574 */ 575 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s", 576 zhp->zfs_name, sdd->fromsnap); 577 if (ioctl(zhp->zfs_hdl->libzfs_fd, 578 ZFS_IOC_OBJSET_STATS, &zc) != 0) { 579 missingfrom = B_TRUE; 580 } 581 } 582 583 if (sdd->doall) { 584 sdd->seenfrom = sdd->seento = sdd->lastsnap[0] = 0; 585 if (sdd->fromsnap == NULL || missingfrom) 586 sdd->seenfrom = B_TRUE; 587 588 rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg); 589 if (!sdd->seenfrom) { 590 (void) fprintf(stderr, 591 "WARNING: could not send %s@%s:\n" 592 "incremental source (%s@%s) does not exist\n", 593 zhp->zfs_name, sdd->tosnap, 594 zhp->zfs_name, sdd->fromsnap); 595 sdd->err = B_TRUE; 596 } else if (!sdd->seento) { 597 (void) fprintf(stderr, 598 "WARNING: could not send %s@%s:\n" 599 "incremental source (%s@%s) " 600 "is not earlier than it\n", 601 zhp->zfs_name, sdd->tosnap, 602 zhp->zfs_name, sdd->fromsnap); 603 sdd->err = B_TRUE; 604 } 605 } else { 606 zfs_handle_t *snapzhp; 607 char snapname[ZFS_MAXNAMELEN]; 608 609 (void) snprintf(snapname, sizeof (snapname), "%s@%s", 610 zfs_get_name(zhp), sdd->tosnap); 611 snapzhp = zfs_open(zhp->zfs_hdl, snapname, ZFS_TYPE_SNAPSHOT); 612 if (snapzhp == NULL) { 613 rv = -1; 614 } else { 615 rv = dump_ioctl(snapzhp, 616 missingfrom ? NULL : sdd->fromsnap, 617 sdd->fromorigin || missingfrom, 618 sdd->outfd); 619 sdd->seento = B_TRUE; 620 zfs_close(snapzhp); 621 } 622 } 623 624 return (rv); 625 } 626 627 static int 628 dump_filesystems(zfs_handle_t *rzhp, void *arg) 629 { 630 send_dump_data_t *sdd = arg; 631 nvpair_t *fspair; 632 boolean_t needagain, progress; 633 634 if (!sdd->replicate) 635 return (dump_filesystem(rzhp, sdd)); 636 637 again: 638 needagain = progress = B_FALSE; 639 for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair; 640 fspair = nvlist_next_nvpair(sdd->fss, fspair)) { 641 nvlist_t *fslist; 642 char *fsname; 643 zfs_handle_t *zhp; 644 int err; 645 uint64_t origin_guid = 0; 646 nvlist_t *origin_nv; 647 648 VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0); 649 if (nvlist_lookup_boolean(fslist, "sent") == 0) 650 continue; 651 652 VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0); 653 (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid); 654 655 origin_nv = fsavl_find(sdd->fsavl, origin_guid, NULL); 656 if (origin_nv && 657 nvlist_lookup_boolean(origin_nv, "sent") == ENOENT) { 658 /* 659 * origin has not been sent yet; 660 * skip this clone. 661 */ 662 needagain = B_TRUE; 663 continue; 664 } 665 666 zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET); 667 if (zhp == NULL) 668 return (-1); 669 err = dump_filesystem(zhp, sdd); 670 VERIFY(nvlist_add_boolean(fslist, "sent") == 0); 671 progress = B_TRUE; 672 zfs_close(zhp); 673 if (err) 674 return (err); 675 } 676 if (needagain) { 677 assert(progress); 678 goto again; 679 } 680 return (0); 681 } 682 683 /* 684 * Dumps a backup of tosnap, incremental from fromsnap if it isn't NULL. 685 * If 'doall', dump all intermediate snaps. 686 * If 'replicate', dump special header and do recursively. 687 */ 688 int 689 zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, 690 boolean_t replicate, boolean_t doall, boolean_t fromorigin, 691 boolean_t verbose, int outfd) 692 { 693 char errbuf[1024]; 694 send_dump_data_t sdd = { 0 }; 695 int err; 696 nvlist_t *fss = NULL; 697 avl_tree_t *fsavl = NULL; 698 699 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 700 "cannot send '%s'"), zhp->zfs_name); 701 702 if (fromsnap && fromsnap[0] == '\0') { 703 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 704 "zero-length incremental source")); 705 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf)); 706 } 707 708 if (replicate || doall) { 709 dmu_replay_record_t drr = { 0 }; 710 char *packbuf = NULL; 711 size_t buflen = 0; 712 zio_cksum_t zc = { 0 }; 713 714 assert(fromsnap || doall); 715 716 if (replicate) { 717 nvlist_t *hdrnv; 718 719 VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0)); 720 if (fromsnap) { 721 VERIFY(0 == nvlist_add_string(hdrnv, 722 "fromsnap", fromsnap)); 723 } 724 VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap)); 725 726 err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name, 727 fromsnap, tosnap, &fss, &fsavl); 728 if (err) 729 return (err); 730 VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss)); 731 err = nvlist_pack(hdrnv, &packbuf, &buflen, 732 NV_ENCODE_XDR, 0); 733 nvlist_free(hdrnv); 734 if (err) { 735 fsavl_destroy(fsavl); 736 nvlist_free(fss); 737 return (zfs_standard_error(zhp->zfs_hdl, 738 err, errbuf)); 739 } 740 } 741 742 /* write first begin record */ 743 drr.drr_type = DRR_BEGIN; 744 drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC; 745 drr.drr_u.drr_begin.drr_version = DMU_BACKUP_HEADER_VERSION; 746 (void) snprintf(drr.drr_u.drr_begin.drr_toname, 747 sizeof (drr.drr_u.drr_begin.drr_toname), 748 "%s@%s", zhp->zfs_name, tosnap); 749 drr.drr_payloadlen = buflen; 750 fletcher_4_incremental_native(&drr, sizeof (drr), &zc); 751 err = write(outfd, &drr, sizeof (drr)); 752 753 /* write header nvlist */ 754 if (err != -1) { 755 fletcher_4_incremental_native(packbuf, buflen, &zc); 756 err = write(outfd, packbuf, buflen); 757 } 758 free(packbuf); 759 if (err == -1) { 760 fsavl_destroy(fsavl); 761 nvlist_free(fss); 762 return (zfs_standard_error(zhp->zfs_hdl, 763 errno, errbuf)); 764 } 765 766 /* write end record */ 767 if (err != -1) { 768 bzero(&drr, sizeof (drr)); 769 drr.drr_type = DRR_END; 770 drr.drr_u.drr_end.drr_checksum = zc; 771 err = write(outfd, &drr, sizeof (drr)); 772 if (err == -1) { 773 fsavl_destroy(fsavl); 774 nvlist_free(fss); 775 return (zfs_standard_error(zhp->zfs_hdl, 776 errno, errbuf)); 777 } 778 } 779 } 780 781 /* dump each stream */ 782 sdd.fromsnap = fromsnap; 783 sdd.tosnap = tosnap; 784 sdd.outfd = outfd; 785 sdd.replicate = replicate; 786 sdd.doall = doall; 787 sdd.fromorigin = fromorigin; 788 sdd.fss = fss; 789 sdd.fsavl = fsavl; 790 sdd.verbose = verbose; 791 err = dump_filesystems(zhp, &sdd); 792 fsavl_destroy(fsavl); 793 nvlist_free(fss); 794 795 if (replicate || doall) { 796 /* 797 * write final end record. NB: want to do this even if 798 * there was some error, because it might not be totally 799 * failed. 800 */ 801 dmu_replay_record_t drr = { 0 }; 802 drr.drr_type = DRR_END; 803 if (write(outfd, &drr, sizeof (drr)) == -1) { 804 return (zfs_standard_error(zhp->zfs_hdl, 805 errno, errbuf)); 806 } 807 } 808 809 return (err || sdd.err); 810 } 811 812 /* 813 * Routines specific to "zfs recv" 814 */ 815 816 static int 817 recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen, 818 boolean_t byteswap, zio_cksum_t *zc) 819 { 820 char *cp = buf; 821 int rv; 822 int len = ilen; 823 824 do { 825 rv = read(fd, cp, len); 826 cp += rv; 827 len -= rv; 828 } while (rv > 0); 829 830 if (rv < 0 || len != 0) { 831 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 832 "failed to read from stream")); 833 return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN, 834 "cannot receive"))); 835 } 836 837 if (zc) { 838 if (byteswap) 839 fletcher_4_incremental_byteswap(buf, ilen, zc); 840 else 841 fletcher_4_incremental_native(buf, ilen, zc); 842 } 843 return (0); 844 } 845 846 static int 847 recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp, 848 boolean_t byteswap, zio_cksum_t *zc) 849 { 850 char *buf; 851 int err; 852 853 buf = zfs_alloc(hdl, len); 854 if (buf == NULL) 855 return (ENOMEM); 856 857 err = recv_read(hdl, fd, buf, len, byteswap, zc); 858 if (err != 0) { 859 free(buf); 860 return (err); 861 } 862 863 err = nvlist_unpack(buf, len, nvp, 0); 864 free(buf); 865 if (err != 0) { 866 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 867 "stream (malformed nvlist)")); 868 return (EINVAL); 869 } 870 return (0); 871 } 872 873 static int 874 recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname, 875 int baselen, char *newname, recvflags_t flags) 876 { 877 static int seq; 878 zfs_cmd_t zc = { 0 }; 879 int err; 880 prop_changelist_t *clp; 881 zfs_handle_t *zhp; 882 883 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); 884 if (zhp == NULL) 885 return (-1); 886 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 887 flags.force ? MS_FORCE : 0); 888 zfs_close(zhp); 889 if (clp == NULL) 890 return (-1); 891 err = changelist_prefix(clp); 892 if (err) 893 return (err); 894 895 if (tryname) { 896 (void) strcpy(newname, tryname); 897 898 zc.zc_objset_type = DMU_OST_ZFS; 899 (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name)); 900 (void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value)); 901 902 if (flags.verbose) { 903 (void) printf("attempting rename %s to %s\n", 904 zc.zc_name, zc.zc_value); 905 } 906 err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc); 907 if (err == 0) 908 changelist_rename(clp, name, tryname); 909 } else { 910 err = ENOENT; 911 } 912 913 if (err != 0 && strncmp(name+baselen, "recv-", 5) != 0) { 914 seq++; 915 916 (void) strncpy(newname, name, baselen); 917 (void) snprintf(newname+baselen, ZFS_MAXNAMELEN-baselen, 918 "recv-%u-%u", getpid(), seq); 919 (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value)); 920 921 if (flags.verbose) { 922 (void) printf("failed - trying rename %s to %s\n", 923 zc.zc_name, zc.zc_value); 924 } 925 err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc); 926 if (err == 0) 927 changelist_rename(clp, name, newname); 928 if (err && flags.verbose) { 929 (void) printf("failed (%u) - " 930 "will try again on next pass\n", errno); 931 } 932 err = EAGAIN; 933 } else if (flags.verbose) { 934 if (err == 0) 935 (void) printf("success\n"); 936 else 937 (void) printf("failed (%u)\n", errno); 938 } 939 940 (void) changelist_postfix(clp); 941 changelist_free(clp); 942 943 return (err); 944 } 945 946 static int 947 recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen, 948 char *newname, recvflags_t flags) 949 { 950 zfs_cmd_t zc = { 0 }; 951 int err = 0; 952 prop_changelist_t *clp; 953 zfs_handle_t *zhp; 954 955 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); 956 if (zhp == NULL) 957 return (-1); 958 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 959 flags.force ? MS_FORCE : 0); 960 zfs_close(zhp); 961 if (clp == NULL) 962 return (-1); 963 err = changelist_prefix(clp); 964 if (err) 965 return (err); 966 967 zc.zc_objset_type = DMU_OST_ZFS; 968 (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name)); 969 970 if (flags.verbose) 971 (void) printf("attempting destroy %s\n", zc.zc_name); 972 err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc); 973 974 if (err == 0) { 975 if (flags.verbose) 976 (void) printf("success\n"); 977 changelist_remove(clp, zc.zc_name); 978 } 979 980 (void) changelist_postfix(clp); 981 changelist_free(clp); 982 983 if (err != 0) 984 err = recv_rename(hdl, name, NULL, baselen, newname, flags); 985 986 return (err); 987 } 988 989 typedef struct guid_to_name_data { 990 uint64_t guid; 991 char *name; 992 } guid_to_name_data_t; 993 994 static int 995 guid_to_name_cb(zfs_handle_t *zhp, void *arg) 996 { 997 guid_to_name_data_t *gtnd = arg; 998 int err; 999 1000 if (zhp->zfs_dmustats.dds_guid == gtnd->guid) { 1001 (void) strcpy(gtnd->name, zhp->zfs_name); 1002 return (EEXIST); 1003 } 1004 err = zfs_iter_children(zhp, guid_to_name_cb, gtnd); 1005 zfs_close(zhp); 1006 return (err); 1007 } 1008 1009 static int 1010 guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid, 1011 char *name) 1012 { 1013 /* exhaustive search all local snapshots */ 1014 guid_to_name_data_t gtnd; 1015 int err = 0; 1016 zfs_handle_t *zhp; 1017 char *cp; 1018 1019 gtnd.guid = guid; 1020 gtnd.name = name; 1021 1022 if (strchr(parent, '@') == NULL) { 1023 zhp = make_dataset_handle(hdl, parent); 1024 if (zhp != NULL) { 1025 err = zfs_iter_children(zhp, guid_to_name_cb, >nd); 1026 zfs_close(zhp); 1027 if (err == EEXIST) 1028 return (0); 1029 } 1030 } 1031 1032 cp = strchr(parent, '/'); 1033 if (cp) 1034 *cp = '\0'; 1035 zhp = make_dataset_handle(hdl, parent); 1036 if (cp) 1037 *cp = '/'; 1038 1039 if (zhp) { 1040 err = zfs_iter_children(zhp, guid_to_name_cb, >nd); 1041 zfs_close(zhp); 1042 } 1043 1044 return (err == EEXIST ? 0 : ENOENT); 1045 1046 } 1047 1048 /* 1049 * Return true if dataset guid1 is created before guid2. 1050 */ 1051 static int 1052 created_before(libzfs_handle_t *hdl, avl_tree_t *avl, 1053 uint64_t guid1, uint64_t guid2) 1054 { 1055 nvlist_t *nvfs; 1056 char *fsname, *snapname; 1057 char buf[ZFS_MAXNAMELEN]; 1058 int rv; 1059 zfs_node_t zn1, zn2; 1060 1061 if (guid2 == 0) 1062 return (0); 1063 if (guid1 == 0) 1064 return (1); 1065 1066 nvfs = fsavl_find(avl, guid1, &snapname); 1067 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname)); 1068 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname); 1069 zn1.zn_handle = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT); 1070 if (zn1.zn_handle == NULL) 1071 return (-1); 1072 1073 nvfs = fsavl_find(avl, guid2, &snapname); 1074 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname)); 1075 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname); 1076 zn2.zn_handle = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT); 1077 if (zn2.zn_handle == NULL) { 1078 zfs_close(zn2.zn_handle); 1079 return (-1); 1080 } 1081 1082 rv = (zfs_snapshot_compare(&zn1, &zn2) == -1); 1083 1084 zfs_close(zn1.zn_handle); 1085 zfs_close(zn2.zn_handle); 1086 1087 return (rv); 1088 } 1089 1090 static int 1091 recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs, 1092 recvflags_t flags, nvlist_t *stream_nv, avl_tree_t *stream_avl) 1093 { 1094 nvlist_t *local_nv; 1095 avl_tree_t *local_avl; 1096 nvpair_t *fselem, *nextfselem; 1097 char *tosnap, *fromsnap; 1098 char newname[ZFS_MAXNAMELEN]; 1099 int error; 1100 boolean_t needagain, progress; 1101 1102 VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap)); 1103 VERIFY(0 == nvlist_lookup_string(stream_nv, "tosnap", &tosnap)); 1104 1105 if (flags.dryrun) 1106 return (0); 1107 1108 again: 1109 needagain = progress = B_FALSE; 1110 1111 if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL, 1112 &local_nv, &local_avl)) != 0) 1113 return (error); 1114 1115 /* 1116 * Process deletes and renames 1117 */ 1118 for (fselem = nvlist_next_nvpair(local_nv, NULL); 1119 fselem; fselem = nextfselem) { 1120 nvlist_t *nvfs, *snaps; 1121 nvlist_t *stream_nvfs = NULL; 1122 nvpair_t *snapelem, *nextsnapelem; 1123 uint64_t fromguid = 0; 1124 uint64_t originguid = 0; 1125 uint64_t stream_originguid = 0; 1126 uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid; 1127 char *fsname, *stream_fsname; 1128 1129 nextfselem = nvlist_next_nvpair(local_nv, fselem); 1130 1131 VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs)); 1132 VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps)); 1133 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname)); 1134 VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap", 1135 &parent_fromsnap_guid)); 1136 (void) nvlist_lookup_uint64(nvfs, "origin", &originguid); 1137 1138 /* 1139 * First find the stream's fs, so we can check for 1140 * a different origin (due to "zfs promote") 1141 */ 1142 for (snapelem = nvlist_next_nvpair(snaps, NULL); 1143 snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) { 1144 uint64_t thisguid; 1145 1146 VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid)); 1147 stream_nvfs = fsavl_find(stream_avl, thisguid, NULL); 1148 1149 if (stream_nvfs != NULL) 1150 break; 1151 } 1152 1153 /* check for promote */ 1154 (void) nvlist_lookup_uint64(stream_nvfs, "origin", 1155 &stream_originguid); 1156 if (stream_nvfs && originguid != stream_originguid) { 1157 switch (created_before(hdl, local_avl, 1158 stream_originguid, originguid)) { 1159 case 1: { 1160 /* promote it! */ 1161 zfs_cmd_t zc = { 0 }; 1162 nvlist_t *origin_nvfs; 1163 char *origin_fsname; 1164 1165 if (flags.verbose) 1166 (void) printf("promoting %s\n", fsname); 1167 1168 origin_nvfs = fsavl_find(local_avl, originguid, 1169 NULL); 1170 VERIFY(0 == nvlist_lookup_string(origin_nvfs, 1171 "name", &origin_fsname)); 1172 (void) strlcpy(zc.zc_value, origin_fsname, 1173 sizeof (zc.zc_value)); 1174 (void) strlcpy(zc.zc_name, fsname, 1175 sizeof (zc.zc_name)); 1176 error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc); 1177 if (error == 0) 1178 progress = B_TRUE; 1179 break; 1180 } 1181 default: 1182 break; 1183 case -1: 1184 fsavl_destroy(local_avl); 1185 nvlist_free(local_nv); 1186 return (-1); 1187 } 1188 /* 1189 * We had/have the wrong origin, therefore our 1190 * list of snapshots is wrong. Need to handle 1191 * them on the next pass. 1192 */ 1193 needagain = B_TRUE; 1194 continue; 1195 } 1196 1197 for (snapelem = nvlist_next_nvpair(snaps, NULL); 1198 snapelem; snapelem = nextsnapelem) { 1199 uint64_t thisguid; 1200 char *stream_snapname; 1201 nvlist_t *found, *props; 1202 1203 nextsnapelem = nvlist_next_nvpair(snaps, snapelem); 1204 1205 VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid)); 1206 found = fsavl_find(stream_avl, thisguid, 1207 &stream_snapname); 1208 1209 /* check for delete */ 1210 if (found == NULL) { 1211 char name[ZFS_MAXNAMELEN]; 1212 1213 if (!flags.force) 1214 continue; 1215 1216 (void) snprintf(name, sizeof (name), "%s@%s", 1217 fsname, nvpair_name(snapelem)); 1218 1219 error = recv_destroy(hdl, name, 1220 strlen(fsname)+1, newname, flags); 1221 if (error) 1222 needagain = B_TRUE; 1223 else 1224 progress = B_TRUE; 1225 continue; 1226 } 1227 1228 stream_nvfs = found; 1229 1230 if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops", 1231 &props) && 0 == nvlist_lookup_nvlist(props, 1232 stream_snapname, &props)) { 1233 zfs_cmd_t zc = { 0 }; 1234 1235 zc.zc_cookie = B_TRUE; /* clear current props */ 1236 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), 1237 "%s@%s", fsname, nvpair_name(snapelem)); 1238 if (zcmd_write_src_nvlist(hdl, &zc, 1239 props) == 0) { 1240 (void) zfs_ioctl(hdl, 1241 ZFS_IOC_SET_PROP, &zc); 1242 zcmd_free_nvlists(&zc); 1243 } 1244 } 1245 1246 /* check for different snapname */ 1247 if (strcmp(nvpair_name(snapelem), 1248 stream_snapname) != 0) { 1249 char name[ZFS_MAXNAMELEN]; 1250 char tryname[ZFS_MAXNAMELEN]; 1251 1252 (void) snprintf(name, sizeof (name), "%s@%s", 1253 fsname, nvpair_name(snapelem)); 1254 (void) snprintf(tryname, sizeof (name), "%s@%s", 1255 fsname, stream_snapname); 1256 1257 error = recv_rename(hdl, name, tryname, 1258 strlen(fsname)+1, newname, flags); 1259 if (error) 1260 needagain = B_TRUE; 1261 else 1262 progress = B_TRUE; 1263 } 1264 1265 if (strcmp(stream_snapname, fromsnap) == 0) 1266 fromguid = thisguid; 1267 } 1268 1269 /* check for delete */ 1270 if (stream_nvfs == NULL) { 1271 if (!flags.force) 1272 continue; 1273 1274 error = recv_destroy(hdl, fsname, strlen(tofs)+1, 1275 newname, flags); 1276 if (error) 1277 needagain = B_TRUE; 1278 else 1279 progress = B_TRUE; 1280 continue; 1281 } 1282 1283 if (fromguid == 0 && flags.verbose) { 1284 (void) printf("local fs %s does not have fromsnap " 1285 "(%s in stream); must have been deleted locally; " 1286 "ignoring\n", fsname, fromsnap); 1287 continue; 1288 } 1289 1290 VERIFY(0 == nvlist_lookup_string(stream_nvfs, 1291 "name", &stream_fsname)); 1292 VERIFY(0 == nvlist_lookup_uint64(stream_nvfs, 1293 "parentfromsnap", &stream_parent_fromsnap_guid)); 1294 1295 /* check for rename */ 1296 if ((stream_parent_fromsnap_guid != 0 && 1297 stream_parent_fromsnap_guid != parent_fromsnap_guid) || 1298 strcmp(strrchr(fsname, '/'), 1299 strrchr(stream_fsname, '/')) != 0) { 1300 nvlist_t *parent; 1301 char tryname[ZFS_MAXNAMELEN]; 1302 1303 parent = fsavl_find(local_avl, 1304 stream_parent_fromsnap_guid, NULL); 1305 /* 1306 * NB: parent might not be found if we used the 1307 * tosnap for stream_parent_fromsnap_guid, 1308 * because the parent is a newly-created fs; 1309 * we'll be able to rename it after we recv the 1310 * new fs. 1311 */ 1312 if (parent != NULL) { 1313 char *pname; 1314 1315 VERIFY(0 == nvlist_lookup_string(parent, "name", 1316 &pname)); 1317 (void) snprintf(tryname, sizeof (tryname), 1318 "%s%s", pname, strrchr(stream_fsname, '/')); 1319 } else { 1320 tryname[0] = '\0'; 1321 if (flags.verbose) { 1322 (void) printf("local fs %s new parent " 1323 "not found\n", fsname); 1324 } 1325 } 1326 1327 error = recv_rename(hdl, fsname, tryname, 1328 strlen(tofs)+1, newname, flags); 1329 if (error) 1330 needagain = B_TRUE; 1331 else 1332 progress = B_TRUE; 1333 } 1334 } 1335 1336 fsavl_destroy(local_avl); 1337 nvlist_free(local_nv); 1338 1339 if (needagain && progress) { 1340 /* do another pass to fix up temporary names */ 1341 if (flags.verbose) 1342 (void) printf("another pass:\n"); 1343 goto again; 1344 } 1345 1346 return (needagain); 1347 } 1348 1349 static int 1350 zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname, 1351 recvflags_t flags, dmu_replay_record_t *drr, zio_cksum_t *zc, 1352 char **top_zfs) 1353 { 1354 nvlist_t *stream_nv = NULL; 1355 avl_tree_t *stream_avl = NULL; 1356 char *fromsnap = NULL; 1357 char tofs[ZFS_MAXNAMELEN]; 1358 char errbuf[1024]; 1359 dmu_replay_record_t drre; 1360 int error; 1361 boolean_t anyerr = B_FALSE; 1362 boolean_t softerr = B_FALSE; 1363 1364 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1365 "cannot receive")); 1366 1367 if (strchr(destname, '@')) { 1368 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1369 "can not specify snapshot name for multi-snapshot stream")); 1370 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 1371 } 1372 1373 assert(drr->drr_type == DRR_BEGIN); 1374 assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC); 1375 assert(drr->drr_u.drr_begin.drr_version == DMU_BACKUP_HEADER_VERSION); 1376 1377 /* 1378 * Read in the nvlist from the stream. 1379 */ 1380 if (drr->drr_payloadlen != 0) { 1381 if (!flags.isprefix) { 1382 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1383 "must use -d to receive replication " 1384 "(send -R) stream")); 1385 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 1386 } 1387 1388 error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen, 1389 &stream_nv, flags.byteswap, zc); 1390 if (error) { 1391 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 1392 goto out; 1393 } 1394 } 1395 1396 /* 1397 * Read in the end record and verify checksum. 1398 */ 1399 if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre), 1400 flags.byteswap, NULL))) 1401 goto out; 1402 if (flags.byteswap) { 1403 drre.drr_type = BSWAP_32(drre.drr_type); 1404 drre.drr_u.drr_end.drr_checksum.zc_word[0] = 1405 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]); 1406 drre.drr_u.drr_end.drr_checksum.zc_word[1] = 1407 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]); 1408 drre.drr_u.drr_end.drr_checksum.zc_word[2] = 1409 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]); 1410 drre.drr_u.drr_end.drr_checksum.zc_word[3] = 1411 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]); 1412 } 1413 if (drre.drr_type != DRR_END) { 1414 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 1415 goto out; 1416 } 1417 if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) { 1418 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1419 "incorrect header checksum")); 1420 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 1421 goto out; 1422 } 1423 1424 (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap); 1425 1426 if (drr->drr_payloadlen != 0) { 1427 nvlist_t *stream_fss; 1428 1429 VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss", 1430 &stream_fss)); 1431 if ((stream_avl = fsavl_create(stream_fss)) == NULL) { 1432 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1433 "couldn't allocate avl tree")); 1434 error = zfs_error(hdl, EZFS_NOMEM, errbuf); 1435 goto out; 1436 } 1437 1438 if (fromsnap != NULL) { 1439 (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN); 1440 if (flags.isprefix) { 1441 int i = strcspn(drr->drr_u.drr_begin.drr_toname, 1442 "/@"); 1443 /* zfs_receive_one() will create_parents() */ 1444 (void) strlcat(tofs, 1445 &drr->drr_u.drr_begin.drr_toname[i], 1446 ZFS_MAXNAMELEN); 1447 *strchr(tofs, '@') = '\0'; 1448 } 1449 softerr = recv_incremental_replication(hdl, tofs, 1450 flags, stream_nv, stream_avl); 1451 } 1452 } 1453 1454 1455 /* Finally, receive each contained stream */ 1456 do { 1457 /* 1458 * we should figure out if it has a recoverable 1459 * error, in which case do a recv_skip() and drive on. 1460 * Note, if we fail due to already having this guid, 1461 * zfs_receive_one() will take care of it (ie, 1462 * recv_skip() and return 0). 1463 */ 1464 error = zfs_receive_impl(hdl, destname, flags, fd, 1465 stream_avl, top_zfs); 1466 if (error == ENODATA) { 1467 error = 0; 1468 break; 1469 } 1470 anyerr |= error; 1471 } while (error == 0); 1472 1473 if (drr->drr_payloadlen != 0 && fromsnap != NULL) { 1474 /* 1475 * Now that we have the fs's they sent us, try the 1476 * renames again. 1477 */ 1478 softerr = recv_incremental_replication(hdl, tofs, flags, 1479 stream_nv, stream_avl); 1480 } 1481 1482 out: 1483 fsavl_destroy(stream_avl); 1484 if (stream_nv) 1485 nvlist_free(stream_nv); 1486 if (softerr) 1487 error = -2; 1488 if (anyerr) 1489 error = -1; 1490 return (error); 1491 } 1492 1493 static int 1494 recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap) 1495 { 1496 dmu_replay_record_t *drr; 1497 void *buf = malloc(1<<20); 1498 1499 /* XXX would be great to use lseek if possible... */ 1500 drr = buf; 1501 1502 while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t), 1503 byteswap, NULL) == 0) { 1504 if (byteswap) 1505 drr->drr_type = BSWAP_32(drr->drr_type); 1506 1507 switch (drr->drr_type) { 1508 case DRR_BEGIN: 1509 /* NB: not to be used on v2 stream packages */ 1510 assert(drr->drr_payloadlen == 0); 1511 break; 1512 1513 case DRR_END: 1514 free(buf); 1515 return (0); 1516 1517 case DRR_OBJECT: 1518 if (byteswap) { 1519 drr->drr_u.drr_object.drr_bonuslen = 1520 BSWAP_32(drr->drr_u.drr_object. 1521 drr_bonuslen); 1522 } 1523 (void) recv_read(hdl, fd, buf, 1524 P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8), 1525 B_FALSE, NULL); 1526 break; 1527 1528 case DRR_WRITE: 1529 if (byteswap) { 1530 drr->drr_u.drr_write.drr_length = 1531 BSWAP_64(drr->drr_u.drr_write.drr_length); 1532 } 1533 (void) recv_read(hdl, fd, buf, 1534 drr->drr_u.drr_write.drr_length, B_FALSE, NULL); 1535 break; 1536 1537 case DRR_FREEOBJECTS: 1538 case DRR_FREE: 1539 break; 1540 1541 default: 1542 assert(!"invalid record type"); 1543 } 1544 } 1545 1546 free(buf); 1547 return (-1); 1548 } 1549 1550 /* 1551 * Restores a backup of tosnap from the file descriptor specified by infd. 1552 */ 1553 static int 1554 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, 1555 recvflags_t flags, dmu_replay_record_t *drr, 1556 dmu_replay_record_t *drr_noswap, avl_tree_t *stream_avl, 1557 char **top_zfs) 1558 { 1559 zfs_cmd_t zc = { 0 }; 1560 time_t begin_time; 1561 int ioctl_err, ioctl_errno, err, choplen; 1562 char *cp; 1563 struct drr_begin *drrb = &drr->drr_u.drr_begin; 1564 char errbuf[1024]; 1565 char chopprefix[ZFS_MAXNAMELEN]; 1566 boolean_t newfs = B_FALSE; 1567 boolean_t stream_wantsnewfs; 1568 uint64_t parent_snapguid = 0; 1569 prop_changelist_t *clp = NULL; 1570 nvlist_t *snapprops_nvlist = NULL; 1571 1572 begin_time = time(NULL); 1573 1574 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1575 "cannot receive")); 1576 1577 if (stream_avl != NULL) { 1578 char *snapname; 1579 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid, 1580 &snapname); 1581 nvlist_t *props; 1582 int ret; 1583 1584 (void) nvlist_lookup_uint64(fs, "parentfromsnap", 1585 &parent_snapguid); 1586 err = nvlist_lookup_nvlist(fs, "props", &props); 1587 if (err) 1588 VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0)); 1589 1590 if (flags.canmountoff) { 1591 VERIFY(0 == nvlist_add_uint64(props, 1592 zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0)); 1593 } 1594 ret = zcmd_write_src_nvlist(hdl, &zc, props); 1595 if (err) 1596 nvlist_free(props); 1597 1598 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) { 1599 VERIFY(0 == nvlist_lookup_nvlist(props, 1600 snapname, &snapprops_nvlist)); 1601 } 1602 1603 if (ret != 0) 1604 return (-1); 1605 } 1606 1607 /* 1608 * Determine how much of the snapshot name stored in the stream 1609 * we are going to tack on to the name they specified on the 1610 * command line, and how much we are going to chop off. 1611 * 1612 * If they specified a snapshot, chop the entire name stored in 1613 * the stream. 1614 */ 1615 (void) strcpy(chopprefix, drrb->drr_toname); 1616 if (flags.isprefix) { 1617 /* 1618 * They specified a fs with -d, we want to tack on 1619 * everything but the pool name stored in the stream 1620 */ 1621 if (strchr(tosnap, '@')) { 1622 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 1623 "argument - snapshot not allowed with -d")); 1624 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 1625 } 1626 cp = strchr(chopprefix, '/'); 1627 if (cp == NULL) 1628 cp = strchr(chopprefix, '@'); 1629 *cp = '\0'; 1630 } else if (strchr(tosnap, '@') == NULL) { 1631 /* 1632 * If they specified a filesystem without -d, we want to 1633 * tack on everything after the fs specified in the 1634 * first name from the stream. 1635 */ 1636 cp = strchr(chopprefix, '@'); 1637 *cp = '\0'; 1638 } 1639 choplen = strlen(chopprefix); 1640 1641 /* 1642 * Determine name of destination snapshot, store in zc_value. 1643 */ 1644 (void) strcpy(zc.zc_value, tosnap); 1645 (void) strncat(zc.zc_value, drrb->drr_toname+choplen, 1646 sizeof (zc.zc_value)); 1647 if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) { 1648 zcmd_free_nvlists(&zc); 1649 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 1650 } 1651 1652 /* 1653 * Determine the name of the origin snapshot, store in zc_string. 1654 */ 1655 if (drrb->drr_flags & DRR_FLAG_CLONE) { 1656 if (guid_to_name(hdl, tosnap, 1657 drrb->drr_fromguid, zc.zc_string) != 0) { 1658 zcmd_free_nvlists(&zc); 1659 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1660 "local origin for clone %s does not exist"), 1661 zc.zc_value); 1662 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 1663 } 1664 if (flags.verbose) 1665 (void) printf("found clone origin %s\n", zc.zc_string); 1666 } 1667 1668 stream_wantsnewfs = (drrb->drr_fromguid == NULL || 1669 (drrb->drr_flags & DRR_FLAG_CLONE)); 1670 1671 if (stream_wantsnewfs) { 1672 /* 1673 * if the parent fs does not exist, look for it based on 1674 * the parent snap GUID 1675 */ 1676 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1677 "cannot receive new filesystem stream")); 1678 1679 (void) strcpy(zc.zc_name, zc.zc_value); 1680 cp = strrchr(zc.zc_name, '/'); 1681 if (cp) 1682 *cp = '\0'; 1683 if (cp && 1684 !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 1685 char suffix[ZFS_MAXNAMELEN]; 1686 (void) strcpy(suffix, strrchr(zc.zc_value, '/')); 1687 if (guid_to_name(hdl, tosnap, parent_snapguid, 1688 zc.zc_value) == 0) { 1689 *strchr(zc.zc_value, '@') = '\0'; 1690 (void) strcat(zc.zc_value, suffix); 1691 } 1692 } 1693 } else { 1694 /* 1695 * if the fs does not exist, look for it based on the 1696 * fromsnap GUID 1697 */ 1698 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1699 "cannot receive incremental stream")); 1700 1701 (void) strcpy(zc.zc_name, zc.zc_value); 1702 *strchr(zc.zc_name, '@') = '\0'; 1703 1704 if (!zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 1705 char snap[ZFS_MAXNAMELEN]; 1706 (void) strcpy(snap, strchr(zc.zc_value, '@')); 1707 if (guid_to_name(hdl, tosnap, drrb->drr_fromguid, 1708 zc.zc_value) == 0) { 1709 *strchr(zc.zc_value, '@') = '\0'; 1710 (void) strcat(zc.zc_value, snap); 1711 } 1712 } 1713 } 1714 1715 (void) strcpy(zc.zc_name, zc.zc_value); 1716 *strchr(zc.zc_name, '@') = '\0'; 1717 1718 if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 1719 zfs_handle_t *zhp; 1720 /* 1721 * Destination fs exists. Therefore this should either 1722 * be an incremental, or the stream specifies a new fs 1723 * (full stream or clone) and they want us to blow it 1724 * away (and have therefore specified -F and removed any 1725 * snapshots). 1726 */ 1727 1728 if (stream_wantsnewfs) { 1729 if (!flags.force) { 1730 zcmd_free_nvlists(&zc); 1731 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1732 "destination '%s' exists\n" 1733 "must specify -F to overwrite it"), 1734 zc.zc_name); 1735 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 1736 } 1737 if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT, 1738 &zc) == 0) { 1739 zcmd_free_nvlists(&zc); 1740 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1741 "destination has snapshots (eg. %s)\n" 1742 "must destroy them to overwrite it"), 1743 zc.zc_name); 1744 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 1745 } 1746 } 1747 1748 if ((zhp = zfs_open(hdl, zc.zc_name, 1749 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) { 1750 zcmd_free_nvlists(&zc); 1751 return (-1); 1752 } 1753 1754 if (stream_wantsnewfs && 1755 zhp->zfs_dmustats.dds_origin[0]) { 1756 zcmd_free_nvlists(&zc); 1757 zfs_close(zhp); 1758 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1759 "destination '%s' is a clone\n" 1760 "must destroy it to overwrite it"), 1761 zc.zc_name); 1762 return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 1763 } 1764 1765 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM && 1766 stream_wantsnewfs) { 1767 /* We can't do online recv in this case */ 1768 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0); 1769 if (clp == NULL) { 1770 zcmd_free_nvlists(&zc); 1771 return (-1); 1772 } 1773 if (changelist_prefix(clp) != 0) { 1774 changelist_free(clp); 1775 zcmd_free_nvlists(&zc); 1776 return (-1); 1777 } 1778 } 1779 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_VOLUME && 1780 zvol_remove_link(hdl, zhp->zfs_name) != 0) { 1781 zfs_close(zhp); 1782 zcmd_free_nvlists(&zc); 1783 return (-1); 1784 } 1785 zfs_close(zhp); 1786 } else { 1787 /* 1788 * Destination filesystem does not exist. Therefore we better 1789 * be creating a new filesystem (either from a full backup, or 1790 * a clone). It would therefore be invalid if the user 1791 * specified only the pool name (i.e. if the destination name 1792 * contained no slash character). 1793 */ 1794 if (!stream_wantsnewfs || 1795 (cp = strrchr(zc.zc_name, '/')) == NULL) { 1796 zcmd_free_nvlists(&zc); 1797 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1798 "destination '%s' does not exist"), zc.zc_name); 1799 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 1800 } 1801 1802 /* 1803 * Trim off the final dataset component so we perform the 1804 * recvbackup ioctl to the filesystems's parent. 1805 */ 1806 *cp = '\0'; 1807 1808 if (flags.isprefix && !flags.dryrun && 1809 create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) { 1810 zcmd_free_nvlists(&zc); 1811 return (zfs_error(hdl, EZFS_BADRESTORE, errbuf)); 1812 } 1813 1814 newfs = B_TRUE; 1815 } 1816 1817 zc.zc_begin_record = drr_noswap->drr_u.drr_begin; 1818 zc.zc_cookie = infd; 1819 zc.zc_guid = flags.force; 1820 if (flags.verbose) { 1821 (void) printf("%s %s stream of %s into %s\n", 1822 flags.dryrun ? "would receive" : "receiving", 1823 drrb->drr_fromguid ? "incremental" : "full", 1824 drrb->drr_toname, zc.zc_value); 1825 (void) fflush(stdout); 1826 } 1827 1828 if (flags.dryrun) { 1829 zcmd_free_nvlists(&zc); 1830 return (recv_skip(hdl, infd, flags.byteswap)); 1831 } 1832 1833 err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc); 1834 ioctl_errno = errno; 1835 zcmd_free_nvlists(&zc); 1836 1837 if (err == 0 && snapprops_nvlist) { 1838 zfs_cmd_t zc2 = { 0 }; 1839 1840 (void) strcpy(zc2.zc_name, zc.zc_value); 1841 if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) { 1842 (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2); 1843 zcmd_free_nvlists(&zc2); 1844 } 1845 } 1846 1847 if (err && (ioctl_errno == ENOENT || ioctl_errno == ENODEV)) { 1848 /* 1849 * It may be that this snapshot already exists, 1850 * in which case we want to consume & ignore it 1851 * rather than failing. 1852 */ 1853 avl_tree_t *local_avl; 1854 nvlist_t *local_nv, *fs; 1855 char *cp = strchr(zc.zc_value, '@'); 1856 1857 /* 1858 * XXX Do this faster by just iterating over snaps in 1859 * this fs. Also if zc_value does not exist, we will 1860 * get a strange "does not exist" error message. 1861 */ 1862 *cp = '\0'; 1863 if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, 1864 &local_nv, &local_avl) == 0) { 1865 *cp = '@'; 1866 fs = fsavl_find(local_avl, drrb->drr_toguid, NULL); 1867 fsavl_destroy(local_avl); 1868 nvlist_free(local_nv); 1869 1870 if (fs != NULL) { 1871 if (flags.verbose) { 1872 (void) printf("snap %s already exists; " 1873 "ignoring\n", zc.zc_value); 1874 } 1875 ioctl_err = recv_skip(hdl, infd, 1876 flags.byteswap); 1877 } 1878 } 1879 *cp = '@'; 1880 } 1881 1882 1883 if (ioctl_err != 0) { 1884 switch (ioctl_errno) { 1885 case ENODEV: 1886 cp = strchr(zc.zc_value, '@'); 1887 *cp = '\0'; 1888 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1889 "most recent snapshot of %s does not\n" 1890 "match incremental source"), zc.zc_value); 1891 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf); 1892 *cp = '@'; 1893 break; 1894 case ETXTBSY: 1895 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1896 "destination %s has been modified\n" 1897 "since most recent snapshot"), zc.zc_name); 1898 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf); 1899 break; 1900 case EEXIST: 1901 cp = strchr(zc.zc_value, '@'); 1902 if (newfs) { 1903 /* it's the containing fs that exists */ 1904 *cp = '\0'; 1905 } 1906 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1907 "destination already exists")); 1908 (void) zfs_error_fmt(hdl, EZFS_EXISTS, 1909 dgettext(TEXT_DOMAIN, "cannot restore to %s"), 1910 zc.zc_value); 1911 *cp = '@'; 1912 break; 1913 case EINVAL: 1914 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf); 1915 break; 1916 case ECKSUM: 1917 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1918 "invalid stream (checksum mismatch)")); 1919 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf); 1920 break; 1921 default: 1922 (void) zfs_standard_error(hdl, ioctl_errno, errbuf); 1923 } 1924 } 1925 1926 /* 1927 * Mount or recreate the /dev links for the target filesystem 1928 * (if created, or if we tore them down to do an incremental 1929 * restore), and the /dev links for the new snapshot (if 1930 * created). Also mount any children of the target filesystem 1931 * if we did an incremental receive. 1932 */ 1933 cp = strchr(zc.zc_value, '@'); 1934 if (cp && (ioctl_err == 0 || !newfs)) { 1935 zfs_handle_t *h; 1936 1937 *cp = '\0'; 1938 h = zfs_open(hdl, zc.zc_value, 1939 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); 1940 if (h != NULL) { 1941 if (h->zfs_type == ZFS_TYPE_VOLUME) { 1942 *cp = '@'; 1943 err = zvol_create_link(hdl, h->zfs_name); 1944 if (err == 0 && ioctl_err == 0) 1945 err = zvol_create_link(hdl, 1946 zc.zc_value); 1947 } else if (newfs) { 1948 /* 1949 * Track the first/top of hierarchy fs, 1950 * for mounting and sharing later. 1951 */ 1952 if (top_zfs && *top_zfs == NULL) 1953 *top_zfs = zfs_strdup(hdl, zc.zc_value); 1954 } 1955 zfs_close(h); 1956 } 1957 *cp = '@'; 1958 } 1959 1960 if (clp) { 1961 err |= changelist_postfix(clp); 1962 changelist_free(clp); 1963 } 1964 1965 if (err || ioctl_err) 1966 return (-1); 1967 1968 if (flags.verbose) { 1969 char buf1[64]; 1970 char buf2[64]; 1971 uint64_t bytes = zc.zc_cookie; 1972 time_t delta = time(NULL) - begin_time; 1973 if (delta == 0) 1974 delta = 1; 1975 zfs_nicenum(bytes, buf1, sizeof (buf1)); 1976 zfs_nicenum(bytes/delta, buf2, sizeof (buf1)); 1977 1978 (void) printf("received %sB stream in %lu seconds (%sB/sec)\n", 1979 buf1, delta, buf2); 1980 } 1981 1982 return (0); 1983 } 1984 1985 static int 1986 zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, 1987 int infd, avl_tree_t *stream_avl, char **top_zfs) 1988 { 1989 int err; 1990 dmu_replay_record_t drr, drr_noswap; 1991 struct drr_begin *drrb = &drr.drr_u.drr_begin; 1992 char errbuf[1024]; 1993 zio_cksum_t zcksum = { 0 }; 1994 1995 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1996 "cannot receive")); 1997 1998 if (flags.isprefix && 1999 !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) { 2000 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs " 2001 "(%s) does not exist"), tosnap); 2002 return (zfs_error(hdl, EZFS_NOENT, errbuf)); 2003 } 2004 2005 /* read in the BEGIN record */ 2006 if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE, 2007 &zcksum))) 2008 return (err); 2009 2010 if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) { 2011 /* It's the double end record at the end of a package */ 2012 return (ENODATA); 2013 } 2014 2015 /* the kernel needs the non-byteswapped begin record */ 2016 drr_noswap = drr; 2017 2018 flags.byteswap = B_FALSE; 2019 if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) { 2020 /* 2021 * We computed the checksum in the wrong byteorder in 2022 * recv_read() above; do it again correctly. 2023 */ 2024 bzero(&zcksum, sizeof (zio_cksum_t)); 2025 fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum); 2026 flags.byteswap = B_TRUE; 2027 2028 drr.drr_type = BSWAP_32(drr.drr_type); 2029 drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen); 2030 drrb->drr_magic = BSWAP_64(drrb->drr_magic); 2031 drrb->drr_version = BSWAP_64(drrb->drr_version); 2032 drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time); 2033 drrb->drr_type = BSWAP_32(drrb->drr_type); 2034 drrb->drr_flags = BSWAP_32(drrb->drr_flags); 2035 drrb->drr_toguid = BSWAP_64(drrb->drr_toguid); 2036 drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid); 2037 } 2038 2039 if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) { 2040 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 2041 "stream (bad magic number)")); 2042 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 2043 } 2044 2045 if (strchr(drrb->drr_toname, '@') == NULL) { 2046 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 2047 "stream (bad snapshot name)")); 2048 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 2049 } 2050 2051 if (drrb->drr_version == DMU_BACKUP_STREAM_VERSION) { 2052 return (zfs_receive_one(hdl, infd, tosnap, flags, 2053 &drr, &drr_noswap, stream_avl, top_zfs)); 2054 } else if (drrb->drr_version == DMU_BACKUP_HEADER_VERSION) { 2055 return (zfs_receive_package(hdl, infd, tosnap, flags, 2056 &drr, &zcksum, top_zfs)); 2057 } else { 2058 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2059 "stream is unsupported version %llu"), 2060 drrb->drr_version); 2061 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 2062 } 2063 } 2064 2065 /* 2066 * Restores a backup of tosnap from the file descriptor specified by infd. 2067 * Return 0 on total success, -2 if some things couldn't be 2068 * destroyed/renamed/promoted, -1 if some things couldn't be received. 2069 * (-1 will override -2). 2070 */ 2071 int 2072 zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, 2073 int infd, avl_tree_t *stream_avl) 2074 { 2075 char *top_zfs = NULL; 2076 int err; 2077 2078 err = zfs_receive_impl(hdl, tosnap, flags, infd, stream_avl, &top_zfs); 2079 2080 if (err == 0 && top_zfs) { 2081 zfs_handle_t *zhp; 2082 prop_changelist_t *clp; 2083 2084 zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM); 2085 if (zhp != NULL) { 2086 clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, 2087 CL_GATHER_MOUNT_ALWAYS, 0); 2088 zfs_close(zhp); 2089 if (clp != NULL) { 2090 /* mount and share received datasets */ 2091 err = changelist_postfix(clp); 2092 changelist_free(clp); 2093 } 2094 } 2095 if (zhp == NULL || clp == NULL || err) 2096 err = -1; 2097 } 2098 if (top_zfs) 2099 free(top_zfs); 2100 2101 return (err); 2102 } 2103