1 1.1 haad /* 2 1.1 haad * CDDL HEADER START 3 1.1 haad * 4 1.1 haad * The contents of this file are subject to the terms of the 5 1.1 haad * Common Development and Distribution License (the "License"). 6 1.1 haad * You may not use this file except in compliance with the License. 7 1.1 haad * 8 1.1 haad * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1.1 haad * or http://www.opensolaris.org/os/licensing. 10 1.1 haad * See the License for the specific language governing permissions 11 1.1 haad * and limitations under the License. 12 1.1 haad * 13 1.1 haad * When distributing Covered Code, include this CDDL HEADER in each 14 1.1 haad * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1.1 haad * If applicable, add the following below this CDDL HEADER, with the 16 1.1 haad * fields enclosed by brackets "[]" replaced with your own identifying 17 1.1 haad * information: Portions Copyright [yyyy] [name of copyright owner] 18 1.1 haad * 19 1.1 haad * CDDL HEADER END 20 1.1 haad */ 21 1.1 haad 22 1.1 haad /* 23 1.3 chs * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 1.3 chs * Copyright (c) 2011, 2015 by Delphix. All rights reserved. 25 1.3 chs * Copyright (c) 2012, Joyent, Inc. All rights reserved. 26 1.3 chs * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved. 27 1.3 chs * Copyright (c) 2013 Steven Hartland. All rights reserved. 28 1.3 chs * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. 29 1.3 chs * Copyright (c) 2014 Integros [integros.com] 30 1.3 chs * Copyright 2016 Igor Kozhukhov <ikozhukhov (at) gmail.com> 31 1.1 haad */ 32 1.1 haad 33 1.1 haad #include <assert.h> 34 1.1 haad #include <ctype.h> 35 1.1 haad #include <errno.h> 36 1.1 haad #include <libintl.h> 37 1.1 haad #include <stdio.h> 38 1.1 haad #include <stdlib.h> 39 1.1 haad #include <strings.h> 40 1.1 haad #include <unistd.h> 41 1.1 haad #include <stddef.h> 42 1.1 haad #include <fcntl.h> 43 1.3 chs #include <sys/param.h> 44 1.1 haad #include <sys/mount.h> 45 1.2 dsl #include <pthread.h> 46 1.2 dsl #include <umem.h> 47 1.3 chs #include <time.h> 48 1.1 haad 49 1.1 haad #include <libzfs.h> 50 1.3 chs #include <libzfs_core.h> 51 1.1 haad 52 1.1 haad #include "zfs_namecheck.h" 53 1.1 haad #include "zfs_prop.h" 54 1.2 dsl #include "zfs_fletcher.h" 55 1.1 haad #include "libzfs_impl.h" 56 1.3 chs #include <zlib.h> 57 1.2 dsl #include <sha2.h> 58 1.2 dsl #include <sys/zio_checksum.h> 59 1.2 dsl #include <sys/ddt.h> 60 1.1 haad 61 1.3 chs #ifdef __FreeBSD__ 62 1.3 chs extern int zfs_ioctl_version; 63 1.3 chs /* We need to use something for ENODATA. */ 64 1.3 chs #define ENODATA EIDRM 65 1.3 chs #endif 66 1.3 chs 67 1.2 dsl /* in libzfs_dataset.c */ 68 1.2 dsl extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *); 69 1.1 haad 70 1.3 chs static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *, 71 1.3 chs recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int, 72 1.3 chs uint64_t *, const char *); 73 1.3 chs static int guid_to_name(libzfs_handle_t *, const char *, 74 1.3 chs uint64_t, boolean_t, char *); 75 1.1 haad 76 1.2 dsl static const zio_cksum_t zero_cksum = { 0 }; 77 1.2 dsl 78 1.2 dsl typedef struct dedup_arg { 79 1.2 dsl int inputfd; 80 1.2 dsl int outputfd; 81 1.2 dsl libzfs_handle_t *dedup_hdl; 82 1.2 dsl } dedup_arg_t; 83 1.2 dsl 84 1.3 chs typedef struct progress_arg { 85 1.3 chs zfs_handle_t *pa_zhp; 86 1.3 chs int pa_fd; 87 1.3 chs boolean_t pa_parsable; 88 1.3 chs } progress_arg_t; 89 1.3 chs 90 1.2 dsl typedef struct dataref { 91 1.2 dsl uint64_t ref_guid; 92 1.2 dsl uint64_t ref_object; 93 1.2 dsl uint64_t ref_offset; 94 1.2 dsl } dataref_t; 95 1.2 dsl 96 1.2 dsl typedef struct dedup_entry { 97 1.2 dsl struct dedup_entry *dde_next; 98 1.2 dsl zio_cksum_t dde_chksum; 99 1.2 dsl uint64_t dde_prop; 100 1.2 dsl dataref_t dde_ref; 101 1.2 dsl } dedup_entry_t; 102 1.2 dsl 103 1.2 dsl #define MAX_DDT_PHYSMEM_PERCENT 20 104 1.2 dsl #define SMALLEST_POSSIBLE_MAX_DDT_MB 128 105 1.2 dsl 106 1.2 dsl typedef struct dedup_table { 107 1.2 dsl dedup_entry_t **dedup_hash_array; 108 1.2 dsl umem_cache_t *ddecache; 109 1.2 dsl uint64_t max_ddt_size; /* max dedup table size in bytes */ 110 1.2 dsl uint64_t cur_ddt_size; /* current dedup table size in bytes */ 111 1.2 dsl uint64_t ddt_count; 112 1.2 dsl int numhashbits; 113 1.2 dsl boolean_t ddt_full; 114 1.2 dsl } dedup_table_t; 115 1.2 dsl 116 1.2 dsl static int 117 1.2 dsl high_order_bit(uint64_t n) 118 1.2 dsl { 119 1.2 dsl int count; 120 1.2 dsl 121 1.2 dsl for (count = 0; n != 0; count++) 122 1.2 dsl n >>= 1; 123 1.2 dsl return (count); 124 1.2 dsl } 125 1.2 dsl 126 1.2 dsl static size_t 127 1.2 dsl ssread(void *buf, size_t len, FILE *stream) 128 1.2 dsl { 129 1.2 dsl size_t outlen; 130 1.2 dsl 131 1.2 dsl if ((outlen = fread(buf, len, 1, stream)) == 0) 132 1.2 dsl return (0); 133 1.2 dsl 134 1.2 dsl return (outlen); 135 1.2 dsl } 136 1.2 dsl 137 1.2 dsl static void 138 1.2 dsl ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp, 139 1.2 dsl zio_cksum_t *cs, uint64_t prop, dataref_t *dr) 140 1.2 dsl { 141 1.2 dsl dedup_entry_t *dde; 142 1.2 dsl 143 1.2 dsl if (ddt->cur_ddt_size >= ddt->max_ddt_size) { 144 1.2 dsl if (ddt->ddt_full == B_FALSE) { 145 1.2 dsl zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 146 1.2 dsl "Dedup table full. Deduplication will continue " 147 1.2 dsl "with existing table entries")); 148 1.2 dsl ddt->ddt_full = B_TRUE; 149 1.2 dsl } 150 1.2 dsl return; 151 1.2 dsl } 152 1.2 dsl 153 1.2 dsl if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT)) 154 1.2 dsl != NULL) { 155 1.2 dsl assert(*ddepp == NULL); 156 1.2 dsl dde->dde_next = NULL; 157 1.2 dsl dde->dde_chksum = *cs; 158 1.2 dsl dde->dde_prop = prop; 159 1.2 dsl dde->dde_ref = *dr; 160 1.2 dsl *ddepp = dde; 161 1.2 dsl ddt->cur_ddt_size += sizeof (dedup_entry_t); 162 1.2 dsl ddt->ddt_count++; 163 1.2 dsl } 164 1.2 dsl } 165 1.2 dsl 166 1.2 dsl /* 167 1.2 dsl * Using the specified dedup table, do a lookup for an entry with 168 1.2 dsl * the checksum cs. If found, return the block's reference info 169 1.2 dsl * in *dr. Otherwise, insert a new entry in the dedup table, using 170 1.2 dsl * the reference information specified by *dr. 171 1.2 dsl * 172 1.2 dsl * return value: true - entry was found 173 1.2 dsl * false - entry was not found 174 1.2 dsl */ 175 1.2 dsl static boolean_t 176 1.2 dsl ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs, 177 1.2 dsl uint64_t prop, dataref_t *dr) 178 1.2 dsl { 179 1.2 dsl uint32_t hashcode; 180 1.2 dsl dedup_entry_t **ddepp; 181 1.2 dsl 182 1.2 dsl hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits); 183 1.2 dsl 184 1.2 dsl for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL; 185 1.2 dsl ddepp = &((*ddepp)->dde_next)) { 186 1.2 dsl if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs) && 187 1.2 dsl (*ddepp)->dde_prop == prop) { 188 1.2 dsl *dr = (*ddepp)->dde_ref; 189 1.2 dsl return (B_TRUE); 190 1.2 dsl } 191 1.2 dsl } 192 1.2 dsl ddt_hash_append(hdl, ddt, ddepp, cs, prop, dr); 193 1.2 dsl return (B_FALSE); 194 1.2 dsl } 195 1.2 dsl 196 1.2 dsl static int 197 1.3 chs dump_record(dmu_replay_record_t *drr, void *payload, int payload_len, 198 1.3 chs zio_cksum_t *zc, int outfd) 199 1.2 dsl { 200 1.3 chs ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), 201 1.3 chs ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t)); 202 1.3 chs fletcher_4_incremental_native(drr, 203 1.3 chs offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc); 204 1.3 chs if (drr->drr_type != DRR_BEGIN) { 205 1.3 chs ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u. 206 1.3 chs drr_checksum.drr_checksum)); 207 1.3 chs drr->drr_u.drr_checksum.drr_checksum = *zc; 208 1.3 chs } 209 1.3 chs fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum, 210 1.3 chs sizeof (zio_cksum_t), zc); 211 1.3 chs if (write(outfd, drr, sizeof (*drr)) == -1) 212 1.3 chs return (errno); 213 1.3 chs if (payload_len != 0) { 214 1.3 chs fletcher_4_incremental_native(payload, payload_len, zc); 215 1.3 chs if (write(outfd, payload, payload_len) == -1) 216 1.3 chs return (errno); 217 1.3 chs } 218 1.3 chs return (0); 219 1.2 dsl } 220 1.2 dsl 221 1.2 dsl /* 222 1.2 dsl * This function is started in a separate thread when the dedup option 223 1.2 dsl * has been requested. The main send thread determines the list of 224 1.2 dsl * snapshots to be included in the send stream and makes the ioctl calls 225 1.2 dsl * for each one. But instead of having the ioctl send the output to the 226 1.2 dsl * the output fd specified by the caller of zfs_send()), the 227 1.2 dsl * ioctl is told to direct the output to a pipe, which is read by the 228 1.2 dsl * alternate thread running THIS function. This function does the 229 1.2 dsl * dedup'ing by: 230 1.2 dsl * 1. building a dedup table (the DDT) 231 1.2 dsl * 2. doing checksums on each data block and inserting a record in the DDT 232 1.2 dsl * 3. looking for matching checksums, and 233 1.2 dsl * 4. sending a DRR_WRITE_BYREF record instead of a write record whenever 234 1.2 dsl * a duplicate block is found. 235 1.2 dsl * The output of this function then goes to the output fd requested 236 1.2 dsl * by the caller of zfs_send(). 237 1.2 dsl */ 238 1.2 dsl static void * 239 1.2 dsl cksummer(void *arg) 240 1.2 dsl { 241 1.2 dsl dedup_arg_t *dda = arg; 242 1.3 chs char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE); 243 1.2 dsl dmu_replay_record_t thedrr; 244 1.2 dsl dmu_replay_record_t *drr = &thedrr; 245 1.2 dsl FILE *ofp; 246 1.2 dsl int outfd; 247 1.2 dsl dedup_table_t ddt; 248 1.2 dsl zio_cksum_t stream_cksum; 249 1.2 dsl uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); 250 1.2 dsl uint64_t numbuckets; 251 1.2 dsl 252 1.2 dsl ddt.max_ddt_size = 253 1.3 chs MAX((physmem * MAX_DDT_PHYSMEM_PERCENT) / 100, 254 1.3 chs SMALLEST_POSSIBLE_MAX_DDT_MB << 20); 255 1.2 dsl 256 1.3 chs numbuckets = ddt.max_ddt_size / (sizeof (dedup_entry_t)); 257 1.2 dsl 258 1.2 dsl /* 259 1.2 dsl * numbuckets must be a power of 2. Increase number to 260 1.2 dsl * a power of 2 if necessary. 261 1.2 dsl */ 262 1.2 dsl if (!ISP2(numbuckets)) 263 1.2 dsl numbuckets = 1 << high_order_bit(numbuckets); 264 1.2 dsl 265 1.2 dsl ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *)); 266 1.2 dsl ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0, 267 1.2 dsl NULL, NULL, NULL, NULL, NULL, 0); 268 1.2 dsl ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *); 269 1.2 dsl ddt.numhashbits = high_order_bit(numbuckets) - 1; 270 1.2 dsl ddt.ddt_full = B_FALSE; 271 1.2 dsl 272 1.2 dsl outfd = dda->outputfd; 273 1.2 dsl ofp = fdopen(dda->inputfd, "r"); 274 1.3 chs while (ssread(drr, sizeof (*drr), ofp) != 0) { 275 1.2 dsl 276 1.2 dsl switch (drr->drr_type) { 277 1.2 dsl case DRR_BEGIN: 278 1.2 dsl { 279 1.3 chs struct drr_begin *drrb = &drr->drr_u.drr_begin; 280 1.3 chs int fflags; 281 1.3 chs int sz = 0; 282 1.2 dsl ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0); 283 1.2 dsl 284 1.3 chs ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC); 285 1.3 chs 286 1.2 dsl /* set the DEDUP feature flag for this stream */ 287 1.2 dsl fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo); 288 1.2 dsl fflags |= (DMU_BACKUP_FEATURE_DEDUP | 289 1.2 dsl DMU_BACKUP_FEATURE_DEDUPPROPS); 290 1.2 dsl DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags); 291 1.2 dsl 292 1.3 chs if (drr->drr_payloadlen != 0) { 293 1.3 chs sz = drr->drr_payloadlen; 294 1.3 chs 295 1.3 chs if (sz > SPA_MAXBLOCKSIZE) { 296 1.3 chs buf = zfs_realloc(dda->dedup_hdl, buf, 297 1.3 chs SPA_MAXBLOCKSIZE, sz); 298 1.2 dsl } 299 1.2 dsl (void) ssread(buf, sz, ofp); 300 1.2 dsl if (ferror(stdin)) 301 1.2 dsl perror("fread"); 302 1.2 dsl } 303 1.3 chs if (dump_record(drr, buf, sz, &stream_cksum, 304 1.3 chs outfd) != 0) 305 1.3 chs goto out; 306 1.2 dsl break; 307 1.2 dsl } 308 1.2 dsl 309 1.2 dsl case DRR_END: 310 1.2 dsl { 311 1.3 chs struct drr_end *drre = &drr->drr_u.drr_end; 312 1.2 dsl /* use the recalculated checksum */ 313 1.3 chs drre->drr_checksum = stream_cksum; 314 1.3 chs if (dump_record(drr, NULL, 0, &stream_cksum, 315 1.3 chs outfd) != 0) 316 1.2 dsl goto out; 317 1.2 dsl break; 318 1.2 dsl } 319 1.2 dsl 320 1.2 dsl case DRR_OBJECT: 321 1.2 dsl { 322 1.3 chs struct drr_object *drro = &drr->drr_u.drr_object; 323 1.2 dsl if (drro->drr_bonuslen > 0) { 324 1.2 dsl (void) ssread(buf, 325 1.2 dsl P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8), 326 1.2 dsl ofp); 327 1.2 dsl } 328 1.3 chs if (dump_record(drr, buf, 329 1.3 chs P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8), 330 1.3 chs &stream_cksum, outfd) != 0) 331 1.3 chs goto out; 332 1.3 chs break; 333 1.3 chs } 334 1.3 chs 335 1.3 chs case DRR_SPILL: 336 1.3 chs { 337 1.3 chs struct drr_spill *drrs = &drr->drr_u.drr_spill; 338 1.3 chs (void) ssread(buf, drrs->drr_length, ofp); 339 1.3 chs if (dump_record(drr, buf, drrs->drr_length, 340 1.3 chs &stream_cksum, outfd) != 0) 341 1.3 chs goto out; 342 1.2 dsl break; 343 1.2 dsl } 344 1.2 dsl 345 1.2 dsl case DRR_FREEOBJECTS: 346 1.2 dsl { 347 1.3 chs if (dump_record(drr, NULL, 0, &stream_cksum, 348 1.3 chs outfd) != 0) 349 1.2 dsl goto out; 350 1.2 dsl break; 351 1.2 dsl } 352 1.2 dsl 353 1.2 dsl case DRR_WRITE: 354 1.2 dsl { 355 1.3 chs struct drr_write *drrw = &drr->drr_u.drr_write; 356 1.2 dsl dataref_t dataref; 357 1.2 dsl 358 1.2 dsl (void) ssread(buf, drrw->drr_length, ofp); 359 1.2 dsl 360 1.2 dsl /* 361 1.2 dsl * Use the existing checksum if it's dedup-capable, 362 1.2 dsl * else calculate a SHA256 checksum for it. 363 1.2 dsl */ 364 1.2 dsl 365 1.2 dsl if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum, 366 1.2 dsl zero_cksum) || 367 1.2 dsl !DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) { 368 1.2 dsl SHA256_CTX ctx; 369 1.2 dsl zio_cksum_t tmpsha256; 370 1.2 dsl 371 1.2 dsl SHA256Init(&ctx); 372 1.2 dsl SHA256Update(&ctx, buf, drrw->drr_length); 373 1.2 dsl SHA256Final(&tmpsha256, &ctx); 374 1.2 dsl drrw->drr_key.ddk_cksum.zc_word[0] = 375 1.2 dsl BE_64(tmpsha256.zc_word[0]); 376 1.2 dsl drrw->drr_key.ddk_cksum.zc_word[1] = 377 1.2 dsl BE_64(tmpsha256.zc_word[1]); 378 1.2 dsl drrw->drr_key.ddk_cksum.zc_word[2] = 379 1.2 dsl BE_64(tmpsha256.zc_word[2]); 380 1.2 dsl drrw->drr_key.ddk_cksum.zc_word[3] = 381 1.2 dsl BE_64(tmpsha256.zc_word[3]); 382 1.2 dsl drrw->drr_checksumtype = ZIO_CHECKSUM_SHA256; 383 1.2 dsl drrw->drr_checksumflags = DRR_CHECKSUM_DEDUP; 384 1.2 dsl } 385 1.2 dsl 386 1.2 dsl dataref.ref_guid = drrw->drr_toguid; 387 1.2 dsl dataref.ref_object = drrw->drr_object; 388 1.2 dsl dataref.ref_offset = drrw->drr_offset; 389 1.2 dsl 390 1.2 dsl if (ddt_update(dda->dedup_hdl, &ddt, 391 1.2 dsl &drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop, 392 1.2 dsl &dataref)) { 393 1.3 chs dmu_replay_record_t wbr_drr = {0}; 394 1.3 chs struct drr_write_byref *wbr_drrr = 395 1.3 chs &wbr_drr.drr_u.drr_write_byref; 396 1.3 chs 397 1.2 dsl /* block already present in stream */ 398 1.3 chs wbr_drr.drr_type = DRR_WRITE_BYREF; 399 1.3 chs 400 1.2 dsl wbr_drrr->drr_object = drrw->drr_object; 401 1.2 dsl wbr_drrr->drr_offset = drrw->drr_offset; 402 1.2 dsl wbr_drrr->drr_length = drrw->drr_length; 403 1.2 dsl wbr_drrr->drr_toguid = drrw->drr_toguid; 404 1.2 dsl wbr_drrr->drr_refguid = dataref.ref_guid; 405 1.2 dsl wbr_drrr->drr_refobject = 406 1.2 dsl dataref.ref_object; 407 1.2 dsl wbr_drrr->drr_refoffset = 408 1.2 dsl dataref.ref_offset; 409 1.2 dsl 410 1.2 dsl wbr_drrr->drr_checksumtype = 411 1.2 dsl drrw->drr_checksumtype; 412 1.2 dsl wbr_drrr->drr_checksumflags = 413 1.2 dsl drrw->drr_checksumtype; 414 1.2 dsl wbr_drrr->drr_key.ddk_cksum = 415 1.2 dsl drrw->drr_key.ddk_cksum; 416 1.2 dsl wbr_drrr->drr_key.ddk_prop = 417 1.2 dsl drrw->drr_key.ddk_prop; 418 1.2 dsl 419 1.3 chs if (dump_record(&wbr_drr, NULL, 0, 420 1.3 chs &stream_cksum, outfd) != 0) 421 1.2 dsl goto out; 422 1.2 dsl } else { 423 1.2 dsl /* block not previously seen */ 424 1.3 chs if (dump_record(drr, buf, drrw->drr_length, 425 1.3 chs &stream_cksum, outfd) != 0) 426 1.2 dsl goto out; 427 1.2 dsl } 428 1.2 dsl break; 429 1.2 dsl } 430 1.2 dsl 431 1.3 chs case DRR_WRITE_EMBEDDED: 432 1.3 chs { 433 1.3 chs struct drr_write_embedded *drrwe = 434 1.3 chs &drr->drr_u.drr_write_embedded; 435 1.3 chs (void) ssread(buf, 436 1.3 chs P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp); 437 1.3 chs if (dump_record(drr, buf, 438 1.3 chs P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), 439 1.3 chs &stream_cksum, outfd) != 0) 440 1.3 chs goto out; 441 1.3 chs break; 442 1.3 chs } 443 1.3 chs 444 1.2 dsl case DRR_FREE: 445 1.2 dsl { 446 1.3 chs if (dump_record(drr, NULL, 0, &stream_cksum, 447 1.3 chs outfd) != 0) 448 1.2 dsl goto out; 449 1.2 dsl break; 450 1.2 dsl } 451 1.2 dsl 452 1.2 dsl default: 453 1.3 chs (void) fprintf(stderr, "INVALID record type 0x%x\n", 454 1.2 dsl drr->drr_type); 455 1.2 dsl /* should never happen, so assert */ 456 1.2 dsl assert(B_FALSE); 457 1.2 dsl } 458 1.2 dsl } 459 1.2 dsl out: 460 1.2 dsl umem_cache_destroy(ddt.ddecache); 461 1.2 dsl free(ddt.dedup_hash_array); 462 1.2 dsl free(buf); 463 1.2 dsl (void) fclose(ofp); 464 1.2 dsl 465 1.2 dsl return (NULL); 466 1.2 dsl } 467 1.2 dsl 468 1.1 haad /* 469 1.1 haad * Routines for dealing with the AVL tree of fs-nvlists 470 1.1 haad */ 471 1.1 haad typedef struct fsavl_node { 472 1.1 haad avl_node_t fn_node; 473 1.1 haad nvlist_t *fn_nvfs; 474 1.1 haad char *fn_snapname; 475 1.1 haad uint64_t fn_guid; 476 1.1 haad } fsavl_node_t; 477 1.1 haad 478 1.1 haad static int 479 1.1 haad fsavl_compare(const void *arg1, const void *arg2) 480 1.1 haad { 481 1.1 haad const fsavl_node_t *fn1 = arg1; 482 1.1 haad const fsavl_node_t *fn2 = arg2; 483 1.1 haad 484 1.1 haad if (fn1->fn_guid > fn2->fn_guid) 485 1.1 haad return (+1); 486 1.1 haad else if (fn1->fn_guid < fn2->fn_guid) 487 1.1 haad return (-1); 488 1.1 haad else 489 1.1 haad return (0); 490 1.1 haad } 491 1.1 haad 492 1.1 haad /* 493 1.1 haad * Given the GUID of a snapshot, find its containing filesystem and 494 1.1 haad * (optionally) name. 495 1.1 haad */ 496 1.1 haad static nvlist_t * 497 1.1 haad fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname) 498 1.1 haad { 499 1.1 haad fsavl_node_t fn_find; 500 1.1 haad fsavl_node_t *fn; 501 1.1 haad 502 1.1 haad fn_find.fn_guid = snapguid; 503 1.1 haad 504 1.1 haad fn = avl_find(avl, &fn_find, NULL); 505 1.1 haad if (fn) { 506 1.1 haad if (snapname) 507 1.1 haad *snapname = fn->fn_snapname; 508 1.1 haad return (fn->fn_nvfs); 509 1.1 haad } 510 1.1 haad return (NULL); 511 1.1 haad } 512 1.1 haad 513 1.1 haad static void 514 1.1 haad fsavl_destroy(avl_tree_t *avl) 515 1.1 haad { 516 1.1 haad fsavl_node_t *fn; 517 1.1 haad void *cookie; 518 1.1 haad 519 1.1 haad if (avl == NULL) 520 1.1 haad return; 521 1.1 haad 522 1.1 haad cookie = NULL; 523 1.1 haad while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL) 524 1.1 haad free(fn); 525 1.1 haad avl_destroy(avl); 526 1.1 haad free(avl); 527 1.1 haad } 528 1.1 haad 529 1.2 dsl /* 530 1.2 dsl * Given an nvlist, produce an avl tree of snapshots, ordered by guid 531 1.2 dsl */ 532 1.1 haad static avl_tree_t * 533 1.1 haad fsavl_create(nvlist_t *fss) 534 1.1 haad { 535 1.1 haad avl_tree_t *fsavl; 536 1.1 haad nvpair_t *fselem = NULL; 537 1.1 haad 538 1.1 haad if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL) 539 1.1 haad return (NULL); 540 1.1 haad 541 1.1 haad avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t), 542 1.1 haad offsetof(fsavl_node_t, fn_node)); 543 1.1 haad 544 1.1 haad while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) { 545 1.1 haad nvlist_t *nvfs, *snaps; 546 1.1 haad nvpair_t *snapelem = NULL; 547 1.1 haad 548 1.1 haad VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs)); 549 1.1 haad VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps)); 550 1.1 haad 551 1.1 haad while ((snapelem = 552 1.1 haad nvlist_next_nvpair(snaps, snapelem)) != NULL) { 553 1.1 haad fsavl_node_t *fn; 554 1.1 haad uint64_t guid; 555 1.1 haad 556 1.1 haad VERIFY(0 == nvpair_value_uint64(snapelem, &guid)); 557 1.1 haad if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) { 558 1.1 haad fsavl_destroy(fsavl); 559 1.1 haad return (NULL); 560 1.1 haad } 561 1.1 haad fn->fn_nvfs = nvfs; 562 1.1 haad fn->fn_snapname = nvpair_name(snapelem); 563 1.1 haad fn->fn_guid = guid; 564 1.1 haad 565 1.1 haad /* 566 1.1 haad * Note: if there are multiple snaps with the 567 1.1 haad * same GUID, we ignore all but one. 568 1.1 haad */ 569 1.1 haad if (avl_find(fsavl, fn, NULL) == NULL) 570 1.1 haad avl_add(fsavl, fn); 571 1.1 haad else 572 1.1 haad free(fn); 573 1.1 haad } 574 1.1 haad } 575 1.1 haad 576 1.1 haad return (fsavl); 577 1.1 haad } 578 1.1 haad 579 1.1 haad /* 580 1.1 haad * Routines for dealing with the giant nvlist of fs-nvlists, etc. 581 1.1 haad */ 582 1.1 haad typedef struct send_data { 583 1.3 chs /* 584 1.3 chs * assigned inside every recursive call, 585 1.3 chs * restored from *_save on return: 586 1.3 chs * 587 1.3 chs * guid of fromsnap snapshot in parent dataset 588 1.3 chs * txg of fromsnap snapshot in current dataset 589 1.3 chs * txg of tosnap snapshot in current dataset 590 1.3 chs */ 591 1.3 chs 592 1.1 haad uint64_t parent_fromsnap_guid; 593 1.3 chs uint64_t fromsnap_txg; 594 1.3 chs uint64_t tosnap_txg; 595 1.3 chs 596 1.3 chs /* the nvlists get accumulated during depth-first traversal */ 597 1.1 haad nvlist_t *parent_snaps; 598 1.1 haad nvlist_t *fss; 599 1.1 haad nvlist_t *snapprops; 600 1.3 chs 601 1.3 chs /* send-receive configuration, does not change during traversal */ 602 1.3 chs const char *fsname; 603 1.1 haad const char *fromsnap; 604 1.1 haad const char *tosnap; 605 1.2 dsl boolean_t recursive; 606 1.3 chs boolean_t verbose; 607 1.1 haad 608 1.1 haad /* 609 1.1 haad * The header nvlist is of the following format: 610 1.1 haad * { 611 1.1 haad * "tosnap" -> string 612 1.1 haad * "fromsnap" -> string (if incremental) 613 1.1 haad * "fss" -> { 614 1.1 haad * id -> { 615 1.1 haad * 616 1.1 haad * "name" -> string (full name; for debugging) 617 1.1 haad * "parentfromsnap" -> number (guid of fromsnap in parent) 618 1.1 haad * 619 1.1 haad * "props" -> { name -> value (only if set here) } 620 1.1 haad * "snaps" -> { name (lastname) -> number (guid) } 621 1.1 haad * "snapprops" -> { name (lastname) -> { name -> value } } 622 1.1 haad * 623 1.1 haad * "origin" -> number (guid) (if clone) 624 1.1 haad * "sent" -> boolean (not on-disk) 625 1.1 haad * } 626 1.1 haad * } 627 1.1 haad * } 628 1.1 haad * 629 1.1 haad */ 630 1.1 haad } send_data_t; 631 1.1 haad 632 1.1 haad static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv); 633 1.1 haad 634 1.1 haad static int 635 1.1 haad send_iterate_snap(zfs_handle_t *zhp, void *arg) 636 1.1 haad { 637 1.1 haad send_data_t *sd = arg; 638 1.1 haad uint64_t guid = zhp->zfs_dmustats.dds_guid; 639 1.3 chs uint64_t txg = zhp->zfs_dmustats.dds_creation_txg; 640 1.1 haad char *snapname; 641 1.1 haad nvlist_t *nv; 642 1.1 haad 643 1.1 haad snapname = strrchr(zhp->zfs_name, '@')+1; 644 1.1 haad 645 1.3 chs if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) { 646 1.3 chs if (sd->verbose) { 647 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 648 1.3 chs "skipping snapshot %s because it was created " 649 1.3 chs "after the destination snapshot (%s)\n"), 650 1.3 chs zhp->zfs_name, sd->tosnap); 651 1.3 chs } 652 1.3 chs zfs_close(zhp); 653 1.3 chs return (0); 654 1.3 chs } 655 1.3 chs 656 1.1 haad VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid)); 657 1.1 haad /* 658 1.1 haad * NB: if there is no fromsnap here (it's a newly created fs in 659 1.1 haad * an incremental replication), we will substitute the tosnap. 660 1.1 haad */ 661 1.1 haad if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) || 662 1.1 haad (sd->parent_fromsnap_guid == 0 && sd->tosnap && 663 1.1 haad strcmp(snapname, sd->tosnap) == 0)) { 664 1.1 haad sd->parent_fromsnap_guid = guid; 665 1.1 haad } 666 1.1 haad 667 1.1 haad VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0)); 668 1.1 haad send_iterate_prop(zhp, nv); 669 1.1 haad VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv)); 670 1.1 haad nvlist_free(nv); 671 1.1 haad 672 1.1 haad zfs_close(zhp); 673 1.1 haad return (0); 674 1.1 haad } 675 1.1 haad 676 1.1 haad static void 677 1.1 haad send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv) 678 1.1 haad { 679 1.1 haad nvpair_t *elem = NULL; 680 1.1 haad 681 1.1 haad while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) { 682 1.1 haad char *propname = nvpair_name(elem); 683 1.1 haad zfs_prop_t prop = zfs_name_to_prop(propname); 684 1.1 haad nvlist_t *propnv; 685 1.1 haad 686 1.2 dsl if (!zfs_prop_user(propname)) { 687 1.2 dsl /* 688 1.2 dsl * Realistically, this should never happen. However, 689 1.2 dsl * we want the ability to add DSL properties without 690 1.2 dsl * needing to make incompatible version changes. We 691 1.2 dsl * need to ignore unknown properties to allow older 692 1.2 dsl * software to still send datasets containing these 693 1.2 dsl * properties, with the unknown properties elided. 694 1.2 dsl */ 695 1.2 dsl if (prop == ZPROP_INVAL) 696 1.2 dsl continue; 697 1.2 dsl 698 1.2 dsl if (zfs_prop_readonly(prop)) 699 1.2 dsl continue; 700 1.2 dsl } 701 1.1 haad 702 1.1 haad verify(nvpair_value_nvlist(elem, &propnv) == 0); 703 1.2 dsl if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION || 704 1.2 dsl prop == ZFS_PROP_REFQUOTA || 705 1.2 dsl prop == ZFS_PROP_REFRESERVATION) { 706 1.2 dsl char *source; 707 1.1 haad uint64_t value; 708 1.1 haad verify(nvlist_lookup_uint64(propnv, 709 1.1 haad ZPROP_VALUE, &value) == 0); 710 1.1 haad if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) 711 1.1 haad continue; 712 1.2 dsl /* 713 1.2 dsl * May have no source before SPA_VERSION_RECVD_PROPS, 714 1.2 dsl * but is still modifiable. 715 1.2 dsl */ 716 1.2 dsl if (nvlist_lookup_string(propnv, 717 1.2 dsl ZPROP_SOURCE, &source) == 0) { 718 1.2 dsl if ((strcmp(source, zhp->zfs_name) != 0) && 719 1.2 dsl (strcmp(source, 720 1.2 dsl ZPROP_SOURCE_VAL_RECVD) != 0)) 721 1.2 dsl continue; 722 1.2 dsl } 723 1.1 haad } else { 724 1.1 haad char *source; 725 1.1 haad if (nvlist_lookup_string(propnv, 726 1.1 haad ZPROP_SOURCE, &source) != 0) 727 1.1 haad continue; 728 1.2 dsl if ((strcmp(source, zhp->zfs_name) != 0) && 729 1.2 dsl (strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)) 730 1.1 haad continue; 731 1.1 haad } 732 1.1 haad 733 1.1 haad if (zfs_prop_user(propname) || 734 1.1 haad zfs_prop_get_type(prop) == PROP_TYPE_STRING) { 735 1.1 haad char *value; 736 1.1 haad verify(nvlist_lookup_string(propnv, 737 1.1 haad ZPROP_VALUE, &value) == 0); 738 1.1 haad VERIFY(0 == nvlist_add_string(nv, propname, value)); 739 1.1 haad } else { 740 1.1 haad uint64_t value; 741 1.1 haad verify(nvlist_lookup_uint64(propnv, 742 1.1 haad ZPROP_VALUE, &value) == 0); 743 1.1 haad VERIFY(0 == nvlist_add_uint64(nv, propname, value)); 744 1.1 haad } 745 1.1 haad } 746 1.1 haad } 747 1.1 haad 748 1.2 dsl /* 749 1.3 chs * returns snapshot creation txg 750 1.3 chs * and returns 0 if the snapshot does not exist 751 1.3 chs */ 752 1.3 chs static uint64_t 753 1.3 chs get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap) 754 1.3 chs { 755 1.3 chs char name[ZFS_MAX_DATASET_NAME_LEN]; 756 1.3 chs uint64_t txg = 0; 757 1.3 chs 758 1.3 chs if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0') 759 1.3 chs return (txg); 760 1.3 chs 761 1.3 chs (void) snprintf(name, sizeof (name), "%s@%s", fs, snap); 762 1.3 chs if (zfs_dataset_exists(hdl, name, ZFS_TYPE_SNAPSHOT)) { 763 1.3 chs zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT); 764 1.3 chs if (zhp != NULL) { 765 1.3 chs txg = zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG); 766 1.3 chs zfs_close(zhp); 767 1.3 chs } 768 1.3 chs } 769 1.3 chs 770 1.3 chs return (txg); 771 1.3 chs } 772 1.3 chs 773 1.3 chs /* 774 1.2 dsl * recursively generate nvlists describing datasets. See comment 775 1.2 dsl * for the data structure send_data_t above for description of contents 776 1.2 dsl * of the nvlist. 777 1.2 dsl */ 778 1.1 haad static int 779 1.1 haad send_iterate_fs(zfs_handle_t *zhp, void *arg) 780 1.1 haad { 781 1.1 haad send_data_t *sd = arg; 782 1.1 haad nvlist_t *nvfs, *nv; 783 1.2 dsl int rv = 0; 784 1.1 haad uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid; 785 1.3 chs uint64_t fromsnap_txg_save = sd->fromsnap_txg; 786 1.3 chs uint64_t tosnap_txg_save = sd->tosnap_txg; 787 1.3 chs uint64_t txg = zhp->zfs_dmustats.dds_creation_txg; 788 1.1 haad uint64_t guid = zhp->zfs_dmustats.dds_guid; 789 1.3 chs uint64_t fromsnap_txg, tosnap_txg; 790 1.1 haad char guidstring[64]; 791 1.1 haad 792 1.3 chs fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap); 793 1.3 chs if (fromsnap_txg != 0) 794 1.3 chs sd->fromsnap_txg = fromsnap_txg; 795 1.3 chs 796 1.3 chs tosnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->tosnap); 797 1.3 chs if (tosnap_txg != 0) 798 1.3 chs sd->tosnap_txg = tosnap_txg; 799 1.3 chs 800 1.3 chs /* 801 1.3 chs * on the send side, if the current dataset does not have tosnap, 802 1.3 chs * perform two additional checks: 803 1.3 chs * 804 1.3 chs * - skip sending the current dataset if it was created later than 805 1.3 chs * the parent tosnap 806 1.3 chs * - return error if the current dataset was created earlier than 807 1.3 chs * the parent tosnap 808 1.3 chs */ 809 1.3 chs if (sd->tosnap != NULL && tosnap_txg == 0) { 810 1.3 chs if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) { 811 1.3 chs if (sd->verbose) { 812 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 813 1.3 chs "skipping dataset %s: snapshot %s does " 814 1.3 chs "not exist\n"), zhp->zfs_name, sd->tosnap); 815 1.3 chs } 816 1.3 chs } else { 817 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 818 1.3 chs "cannot send %s@%s%s: snapshot %s@%s does not " 819 1.3 chs "exist\n"), sd->fsname, sd->tosnap, sd->recursive ? 820 1.3 chs dgettext(TEXT_DOMAIN, " recursively") : "", 821 1.3 chs zhp->zfs_name, sd->tosnap); 822 1.3 chs rv = -1; 823 1.3 chs } 824 1.3 chs goto out; 825 1.3 chs } 826 1.3 chs 827 1.1 haad VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0)); 828 1.1 haad VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name)); 829 1.1 haad VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap", 830 1.1 haad sd->parent_fromsnap_guid)); 831 1.1 haad 832 1.1 haad if (zhp->zfs_dmustats.dds_origin[0]) { 833 1.1 haad zfs_handle_t *origin = zfs_open(zhp->zfs_hdl, 834 1.1 haad zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT); 835 1.3 chs if (origin == NULL) { 836 1.3 chs rv = -1; 837 1.3 chs goto out; 838 1.3 chs } 839 1.1 haad VERIFY(0 == nvlist_add_uint64(nvfs, "origin", 840 1.1 haad origin->zfs_dmustats.dds_guid)); 841 1.1 haad } 842 1.1 haad 843 1.1 haad /* iterate over props */ 844 1.1 haad VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0)); 845 1.1 haad send_iterate_prop(zhp, nv); 846 1.1 haad VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv)); 847 1.1 haad nvlist_free(nv); 848 1.1 haad 849 1.1 haad /* iterate over snaps, and set sd->parent_fromsnap_guid */ 850 1.1 haad sd->parent_fromsnap_guid = 0; 851 1.1 haad VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0)); 852 1.1 haad VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0)); 853 1.3 chs (void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd); 854 1.1 haad VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps)); 855 1.1 haad VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops)); 856 1.1 haad nvlist_free(sd->parent_snaps); 857 1.1 haad nvlist_free(sd->snapprops); 858 1.1 haad 859 1.1 haad /* add this fs to nvlist */ 860 1.1 haad (void) snprintf(guidstring, sizeof (guidstring), 861 1.1 haad "0x%llx", (longlong_t)guid); 862 1.1 haad VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs)); 863 1.1 haad nvlist_free(nvfs); 864 1.1 haad 865 1.1 haad /* iterate over children */ 866 1.2 dsl if (sd->recursive) 867 1.2 dsl rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd); 868 1.1 haad 869 1.3 chs out: 870 1.1 haad sd->parent_fromsnap_guid = parent_fromsnap_guid_save; 871 1.3 chs sd->fromsnap_txg = fromsnap_txg_save; 872 1.3 chs sd->tosnap_txg = tosnap_txg_save; 873 1.1 haad 874 1.1 haad zfs_close(zhp); 875 1.1 haad return (rv); 876 1.1 haad } 877 1.1 haad 878 1.1 haad static int 879 1.1 haad gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap, 880 1.3 chs const char *tosnap, boolean_t recursive, boolean_t verbose, 881 1.3 chs nvlist_t **nvlp, avl_tree_t **avlp) 882 1.1 haad { 883 1.1 haad zfs_handle_t *zhp; 884 1.1 haad send_data_t sd = { 0 }; 885 1.1 haad int error; 886 1.1 haad 887 1.1 haad zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); 888 1.1 haad if (zhp == NULL) 889 1.1 haad return (EZFS_BADTYPE); 890 1.1 haad 891 1.1 haad VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0)); 892 1.3 chs sd.fsname = fsname; 893 1.1 haad sd.fromsnap = fromsnap; 894 1.1 haad sd.tosnap = tosnap; 895 1.2 dsl sd.recursive = recursive; 896 1.3 chs sd.verbose = verbose; 897 1.1 haad 898 1.1 haad if ((error = send_iterate_fs(zhp, &sd)) != 0) { 899 1.1 haad nvlist_free(sd.fss); 900 1.1 haad if (avlp != NULL) 901 1.1 haad *avlp = NULL; 902 1.1 haad *nvlp = NULL; 903 1.1 haad return (error); 904 1.1 haad } 905 1.1 haad 906 1.1 haad if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) { 907 1.1 haad nvlist_free(sd.fss); 908 1.1 haad *nvlp = NULL; 909 1.1 haad return (EZFS_NOMEM); 910 1.1 haad } 911 1.1 haad 912 1.1 haad *nvlp = sd.fss; 913 1.1 haad return (0); 914 1.1 haad } 915 1.1 haad 916 1.1 haad /* 917 1.3 chs * Routines specific to "zfs send" 918 1.1 haad */ 919 1.3 chs typedef struct send_dump_data { 920 1.3 chs /* these are all just the short snapname (the part after the @) */ 921 1.3 chs const char *fromsnap; 922 1.3 chs const char *tosnap; 923 1.3 chs char prevsnap[ZFS_MAX_DATASET_NAME_LEN]; 924 1.3 chs uint64_t prevsnap_obj; 925 1.3 chs boolean_t seenfrom, seento, replicate, doall, fromorigin; 926 1.3 chs boolean_t verbose, dryrun, parsable, progress, embed_data, std_out; 927 1.3 chs boolean_t large_block; 928 1.3 chs int outfd; 929 1.3 chs boolean_t err; 930 1.3 chs nvlist_t *fss; 931 1.3 chs nvlist_t *snapholds; 932 1.3 chs avl_tree_t *fsavl; 933 1.3 chs snapfilter_cb_t *filter_cb; 934 1.3 chs void *filter_cb_arg; 935 1.3 chs nvlist_t *debugnv; 936 1.3 chs char holdtag[ZFS_MAX_DATASET_NAME_LEN]; 937 1.3 chs int cleanup_fd; 938 1.3 chs uint64_t size; 939 1.3 chs } send_dump_data_t; 940 1.1 haad 941 1.1 haad static int 942 1.3 chs estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj, 943 1.3 chs boolean_t fromorigin, uint64_t *sizep) 944 1.1 haad { 945 1.3 chs zfs_cmd_t zc = { 0 }; 946 1.3 chs libzfs_handle_t *hdl = zhp->zfs_hdl; 947 1.1 haad 948 1.3 chs assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT); 949 1.3 chs assert(fromsnap_obj == 0 || !fromorigin); 950 1.1 haad 951 1.3 chs (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 952 1.3 chs zc.zc_obj = fromorigin; 953 1.3 chs zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID); 954 1.3 chs zc.zc_fromobj = fromsnap_obj; 955 1.3 chs zc.zc_guid = 1; /* estimate flag */ 956 1.1 haad 957 1.3 chs if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) { 958 1.3 chs char errbuf[1024]; 959 1.3 chs (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 960 1.3 chs "warning: cannot estimate space for '%s'"), zhp->zfs_name); 961 1.1 haad 962 1.3 chs switch (errno) { 963 1.3 chs case EXDEV: 964 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 965 1.3 chs "not an earlier snapshot from the same fs")); 966 1.3 chs return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); 967 1.1 haad 968 1.3 chs case ENOENT: 969 1.3 chs if (zfs_dataset_exists(hdl, zc.zc_name, 970 1.3 chs ZFS_TYPE_SNAPSHOT)) { 971 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 972 1.3 chs "incremental source (@%s) does not exist"), 973 1.3 chs zc.zc_value); 974 1.3 chs } 975 1.3 chs return (zfs_error(hdl, EZFS_NOENT, errbuf)); 976 1.1 haad 977 1.3 chs case EDQUOT: 978 1.3 chs case EFBIG: 979 1.3 chs case EIO: 980 1.3 chs case ENOLINK: 981 1.3 chs case ENOSPC: 982 1.3 chs case ENXIO: 983 1.3 chs case EPIPE: 984 1.3 chs case ERANGE: 985 1.3 chs case EFAULT: 986 1.3 chs case EROFS: 987 1.3 chs zfs_error_aux(hdl, strerror(errno)); 988 1.3 chs return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); 989 1.1 haad 990 1.3 chs default: 991 1.3 chs return (zfs_standard_error(hdl, errno, errbuf)); 992 1.3 chs } 993 1.3 chs } 994 1.1 haad 995 1.3 chs *sizep = zc.zc_objset_type; 996 1.1 haad 997 1.3 chs return (0); 998 1.1 haad } 999 1.1 haad 1000 1.1 haad /* 1001 1.1 haad * Dumps a backup of the given snapshot (incremental from fromsnap if it's not 1002 1.1 haad * NULL) to the file descriptor specified by outfd. 1003 1.1 haad */ 1004 1.1 haad static int 1005 1.3 chs dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj, 1006 1.3 chs boolean_t fromorigin, int outfd, enum lzc_send_flags flags, 1007 1.3 chs nvlist_t *debugnv) 1008 1.1 haad { 1009 1.1 haad zfs_cmd_t zc = { 0 }; 1010 1.1 haad libzfs_handle_t *hdl = zhp->zfs_hdl; 1011 1.3 chs nvlist_t *thisdbg; 1012 1.1 haad 1013 1.1 haad assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT); 1014 1.3 chs assert(fromsnap_obj == 0 || !fromorigin); 1015 1.1 haad 1016 1.1 haad (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1017 1.1 haad zc.zc_cookie = outfd; 1018 1.1 haad zc.zc_obj = fromorigin; 1019 1.3 chs zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID); 1020 1.3 chs zc.zc_fromobj = fromsnap_obj; 1021 1.3 chs zc.zc_flags = flags; 1022 1.1 haad 1023 1.3 chs VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0)); 1024 1.3 chs if (fromsnap && fromsnap[0] != '\0') { 1025 1.3 chs VERIFY(0 == nvlist_add_string(thisdbg, 1026 1.3 chs "fromsnap", fromsnap)); 1027 1.3 chs } 1028 1.2 dsl 1029 1.3 chs if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) { 1030 1.1 haad char errbuf[1024]; 1031 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1032 1.1 haad "warning: cannot send '%s'"), zhp->zfs_name); 1033 1.1 haad 1034 1.3 chs VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno)); 1035 1.3 chs if (debugnv) { 1036 1.3 chs VERIFY(0 == nvlist_add_nvlist(debugnv, 1037 1.3 chs zhp->zfs_name, thisdbg)); 1038 1.3 chs } 1039 1.3 chs nvlist_free(thisdbg); 1040 1.3 chs 1041 1.1 haad switch (errno) { 1042 1.1 haad case EXDEV: 1043 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1044 1.1 haad "not an earlier snapshot from the same fs")); 1045 1.1 haad return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); 1046 1.1 haad 1047 1.1 haad case ENOENT: 1048 1.1 haad if (zfs_dataset_exists(hdl, zc.zc_name, 1049 1.1 haad ZFS_TYPE_SNAPSHOT)) { 1050 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1051 1.1 haad "incremental source (@%s) does not exist"), 1052 1.1 haad zc.zc_value); 1053 1.1 haad } 1054 1.1 haad return (zfs_error(hdl, EZFS_NOENT, errbuf)); 1055 1.1 haad 1056 1.1 haad case EDQUOT: 1057 1.1 haad case EFBIG: 1058 1.1 haad case EIO: 1059 1.1 haad case ENOLINK: 1060 1.1 haad case ENOSPC: 1061 1.3 chs #ifdef illumos 1062 1.1 haad case ENOSTR: 1063 1.3 chs #endif 1064 1.1 haad case ENXIO: 1065 1.1 haad case EPIPE: 1066 1.1 haad case ERANGE: 1067 1.1 haad case EFAULT: 1068 1.1 haad case EROFS: 1069 1.1 haad zfs_error_aux(hdl, strerror(errno)); 1070 1.1 haad return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); 1071 1.1 haad 1072 1.1 haad default: 1073 1.1 haad return (zfs_standard_error(hdl, errno, errbuf)); 1074 1.1 haad } 1075 1.1 haad } 1076 1.1 haad 1077 1.3 chs if (debugnv) 1078 1.3 chs VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg)); 1079 1.3 chs nvlist_free(thisdbg); 1080 1.3 chs 1081 1.1 haad return (0); 1082 1.1 haad } 1083 1.1 haad 1084 1.3 chs static void 1085 1.3 chs gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd) 1086 1.3 chs { 1087 1.3 chs assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT); 1088 1.3 chs 1089 1.3 chs /* 1090 1.3 chs * zfs_send() only sets snapholds for sends that need them, 1091 1.3 chs * e.g. replication and doall. 1092 1.3 chs */ 1093 1.3 chs if (sdd->snapholds == NULL) 1094 1.3 chs return; 1095 1.3 chs 1096 1.3 chs fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag); 1097 1.3 chs } 1098 1.3 chs 1099 1.3 chs static void * 1100 1.3 chs send_progress_thread(void *arg) 1101 1.3 chs { 1102 1.3 chs progress_arg_t *pa = arg; 1103 1.3 chs zfs_cmd_t zc = { 0 }; 1104 1.3 chs zfs_handle_t *zhp = pa->pa_zhp; 1105 1.3 chs libzfs_handle_t *hdl = zhp->zfs_hdl; 1106 1.3 chs unsigned long long bytes; 1107 1.3 chs char buf[16]; 1108 1.3 chs time_t t; 1109 1.3 chs struct tm *tm; 1110 1.3 chs 1111 1.3 chs (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 1112 1.3 chs 1113 1.3 chs if (!pa->pa_parsable) 1114 1.3 chs (void) fprintf(stderr, "TIME SENT SNAPSHOT\n"); 1115 1.3 chs 1116 1.3 chs /* 1117 1.3 chs * Print the progress from ZFS_IOC_SEND_PROGRESS every second. 1118 1.3 chs */ 1119 1.3 chs for (;;) { 1120 1.3 chs (void) sleep(1); 1121 1.3 chs 1122 1.3 chs zc.zc_cookie = pa->pa_fd; 1123 1.3 chs if (zfs_ioctl(hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0) 1124 1.3 chs return ((void *)-1); 1125 1.3 chs 1126 1.3 chs (void) time(&t); 1127 1.3 chs tm = localtime(&t); 1128 1.3 chs bytes = zc.zc_cookie; 1129 1.3 chs 1130 1.3 chs if (pa->pa_parsable) { 1131 1.3 chs (void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n", 1132 1.3 chs tm->tm_hour, tm->tm_min, tm->tm_sec, 1133 1.3 chs bytes, zhp->zfs_name); 1134 1.3 chs } else { 1135 1.3 chs zfs_nicenum(bytes, buf, sizeof (buf)); 1136 1.3 chs (void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n", 1137 1.3 chs tm->tm_hour, tm->tm_min, tm->tm_sec, 1138 1.3 chs buf, zhp->zfs_name); 1139 1.3 chs } 1140 1.3 chs } 1141 1.3 chs } 1142 1.3 chs 1143 1.3 chs static void 1144 1.3 chs send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap, 1145 1.3 chs uint64_t size, boolean_t parsable) 1146 1.3 chs { 1147 1.3 chs if (parsable) { 1148 1.3 chs if (fromsnap != NULL) { 1149 1.3 chs (void) fprintf(fout, "incremental\t%s\t%s", 1150 1.3 chs fromsnap, tosnap); 1151 1.3 chs } else { 1152 1.3 chs (void) fprintf(fout, "full\t%s", 1153 1.3 chs tosnap); 1154 1.3 chs } 1155 1.3 chs } else { 1156 1.3 chs if (fromsnap != NULL) { 1157 1.3 chs if (strchr(fromsnap, '@') == NULL && 1158 1.3 chs strchr(fromsnap, '#') == NULL) { 1159 1.3 chs (void) fprintf(fout, dgettext(TEXT_DOMAIN, 1160 1.3 chs "send from @%s to %s"), 1161 1.3 chs fromsnap, tosnap); 1162 1.3 chs } else { 1163 1.3 chs (void) fprintf(fout, dgettext(TEXT_DOMAIN, 1164 1.3 chs "send from %s to %s"), 1165 1.3 chs fromsnap, tosnap); 1166 1.3 chs } 1167 1.3 chs } else { 1168 1.3 chs (void) fprintf(fout, dgettext(TEXT_DOMAIN, 1169 1.3 chs "full send of %s"), 1170 1.3 chs tosnap); 1171 1.3 chs } 1172 1.3 chs } 1173 1.3 chs 1174 1.3 chs if (size != 0) { 1175 1.3 chs if (parsable) { 1176 1.3 chs (void) fprintf(fout, "\t%llu", 1177 1.3 chs (longlong_t)size); 1178 1.3 chs } else { 1179 1.3 chs char buf[16]; 1180 1.3 chs zfs_nicenum(size, buf, sizeof (buf)); 1181 1.3 chs (void) fprintf(fout, dgettext(TEXT_DOMAIN, 1182 1.3 chs " estimated size is %s"), buf); 1183 1.3 chs } 1184 1.3 chs } 1185 1.3 chs (void) fprintf(fout, "\n"); 1186 1.3 chs } 1187 1.3 chs 1188 1.1 haad static int 1189 1.1 haad dump_snapshot(zfs_handle_t *zhp, void *arg) 1190 1.1 haad { 1191 1.1 haad send_dump_data_t *sdd = arg; 1192 1.3 chs progress_arg_t pa = { 0 }; 1193 1.3 chs pthread_t tid; 1194 1.3 chs char *thissnap; 1195 1.1 haad int err; 1196 1.3 chs boolean_t isfromsnap, istosnap, fromorigin; 1197 1.3 chs boolean_t exclude = B_FALSE; 1198 1.3 chs FILE *fout = sdd->std_out ? stdout : stderr; 1199 1.1 haad 1200 1.3 chs err = 0; 1201 1.1 haad thissnap = strchr(zhp->zfs_name, '@') + 1; 1202 1.3 chs isfromsnap = (sdd->fromsnap != NULL && 1203 1.3 chs strcmp(sdd->fromsnap, thissnap) == 0); 1204 1.1 haad 1205 1.3 chs if (!sdd->seenfrom && isfromsnap) { 1206 1.3 chs gather_holds(zhp, sdd); 1207 1.1 haad sdd->seenfrom = B_TRUE; 1208 1.2 dsl (void) strcpy(sdd->prevsnap, thissnap); 1209 1.3 chs sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID); 1210 1.1 haad zfs_close(zhp); 1211 1.1 haad return (0); 1212 1.1 haad } 1213 1.1 haad 1214 1.1 haad if (sdd->seento || !sdd->seenfrom) { 1215 1.1 haad zfs_close(zhp); 1216 1.1 haad return (0); 1217 1.1 haad } 1218 1.1 haad 1219 1.3 chs istosnap = (strcmp(sdd->tosnap, thissnap) == 0); 1220 1.3 chs if (istosnap) 1221 1.2 dsl sdd->seento = B_TRUE; 1222 1.2 dsl 1223 1.3 chs if (!sdd->doall && !isfromsnap && !istosnap) { 1224 1.3 chs if (sdd->replicate) { 1225 1.3 chs char *snapname; 1226 1.3 chs nvlist_t *snapprops; 1227 1.3 chs /* 1228 1.3 chs * Filter out all intermediate snapshots except origin 1229 1.3 chs * snapshots needed to replicate clones. 1230 1.3 chs */ 1231 1.3 chs nvlist_t *nvfs = fsavl_find(sdd->fsavl, 1232 1.3 chs zhp->zfs_dmustats.dds_guid, &snapname); 1233 1.3 chs 1234 1.3 chs VERIFY(0 == nvlist_lookup_nvlist(nvfs, 1235 1.3 chs "snapprops", &snapprops)); 1236 1.3 chs VERIFY(0 == nvlist_lookup_nvlist(snapprops, 1237 1.3 chs thissnap, &snapprops)); 1238 1.3 chs exclude = !nvlist_exists(snapprops, "is_clone_origin"); 1239 1.3 chs } else { 1240 1.3 chs exclude = B_TRUE; 1241 1.3 chs } 1242 1.3 chs } 1243 1.3 chs 1244 1.2 dsl /* 1245 1.2 dsl * If a filter function exists, call it to determine whether 1246 1.2 dsl * this snapshot will be sent. 1247 1.2 dsl */ 1248 1.3 chs if (exclude || (sdd->filter_cb != NULL && 1249 1.3 chs sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) { 1250 1.2 dsl /* 1251 1.2 dsl * This snapshot is filtered out. Don't send it, and don't 1252 1.3 chs * set prevsnap_obj, so it will be as if this snapshot didn't 1253 1.2 dsl * exist, and the next accepted snapshot will be sent as 1254 1.2 dsl * an incremental from the last accepted one, or as the 1255 1.2 dsl * first (and full) snapshot in the case of a replication, 1256 1.2 dsl * non-incremental send. 1257 1.2 dsl */ 1258 1.2 dsl zfs_close(zhp); 1259 1.2 dsl return (0); 1260 1.2 dsl } 1261 1.2 dsl 1262 1.3 chs gather_holds(zhp, sdd); 1263 1.3 chs fromorigin = sdd->prevsnap[0] == '\0' && 1264 1.3 chs (sdd->fromorigin || sdd->replicate); 1265 1.3 chs 1266 1.1 haad if (sdd->verbose) { 1267 1.3 chs uint64_t size = 0; 1268 1.3 chs (void) estimate_ioctl(zhp, sdd->prevsnap_obj, 1269 1.3 chs fromorigin, &size); 1270 1.3 chs 1271 1.3 chs send_print_verbose(fout, zhp->zfs_name, 1272 1.3 chs sdd->prevsnap[0] ? sdd->prevsnap : NULL, 1273 1.3 chs size, sdd->parsable); 1274 1.3 chs sdd->size += size; 1275 1.1 haad } 1276 1.1 haad 1277 1.3 chs if (!sdd->dryrun) { 1278 1.3 chs /* 1279 1.3 chs * If progress reporting is requested, spawn a new thread to 1280 1.3 chs * poll ZFS_IOC_SEND_PROGRESS at a regular interval. 1281 1.3 chs */ 1282 1.3 chs if (sdd->progress) { 1283 1.3 chs pa.pa_zhp = zhp; 1284 1.3 chs pa.pa_fd = sdd->outfd; 1285 1.3 chs pa.pa_parsable = sdd->parsable; 1286 1.3 chs 1287 1.3 chs if ((err = pthread_create(&tid, NULL, 1288 1.3 chs send_progress_thread, &pa)) != 0) { 1289 1.3 chs zfs_close(zhp); 1290 1.3 chs return (err); 1291 1.3 chs } 1292 1.3 chs } 1293 1.3 chs 1294 1.3 chs enum lzc_send_flags flags = 0; 1295 1.3 chs if (sdd->large_block) 1296 1.3 chs flags |= LZC_SEND_FLAG_LARGE_BLOCK; 1297 1.3 chs if (sdd->embed_data) 1298 1.3 chs flags |= LZC_SEND_FLAG_EMBED_DATA; 1299 1.1 haad 1300 1.3 chs err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj, 1301 1.3 chs fromorigin, sdd->outfd, flags, sdd->debugnv); 1302 1.3 chs 1303 1.3 chs if (sdd->progress) { 1304 1.3 chs (void) pthread_cancel(tid); 1305 1.3 chs (void) pthread_join(tid, NULL); 1306 1.3 chs } 1307 1.3 chs } 1308 1.3 chs 1309 1.3 chs (void) strcpy(sdd->prevsnap, thissnap); 1310 1.3 chs sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID); 1311 1.1 haad zfs_close(zhp); 1312 1.1 haad return (err); 1313 1.1 haad } 1314 1.1 haad 1315 1.1 haad static int 1316 1.1 haad dump_filesystem(zfs_handle_t *zhp, void *arg) 1317 1.1 haad { 1318 1.1 haad int rv = 0; 1319 1.1 haad send_dump_data_t *sdd = arg; 1320 1.1 haad boolean_t missingfrom = B_FALSE; 1321 1.1 haad zfs_cmd_t zc = { 0 }; 1322 1.1 haad 1323 1.1 haad (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s", 1324 1.1 haad zhp->zfs_name, sdd->tosnap); 1325 1.1 haad if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) { 1326 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 1327 1.3 chs "WARNING: could not send %s@%s: does not exist\n"), 1328 1.1 haad zhp->zfs_name, sdd->tosnap); 1329 1.1 haad sdd->err = B_TRUE; 1330 1.1 haad return (0); 1331 1.1 haad } 1332 1.1 haad 1333 1.1 haad if (sdd->replicate && sdd->fromsnap) { 1334 1.1 haad /* 1335 1.1 haad * If this fs does not have fromsnap, and we're doing 1336 1.1 haad * recursive, we need to send a full stream from the 1337 1.1 haad * beginning (or an incremental from the origin if this 1338 1.1 haad * is a clone). If we're doing non-recursive, then let 1339 1.1 haad * them get the error. 1340 1.1 haad */ 1341 1.1 haad (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s", 1342 1.1 haad zhp->zfs_name, sdd->fromsnap); 1343 1.1 haad if (ioctl(zhp->zfs_hdl->libzfs_fd, 1344 1.1 haad ZFS_IOC_OBJSET_STATS, &zc) != 0) { 1345 1.1 haad missingfrom = B_TRUE; 1346 1.1 haad } 1347 1.1 haad } 1348 1.1 haad 1349 1.3 chs sdd->seenfrom = sdd->seento = sdd->prevsnap[0] = 0; 1350 1.3 chs sdd->prevsnap_obj = 0; 1351 1.3 chs if (sdd->fromsnap == NULL || missingfrom) 1352 1.3 chs sdd->seenfrom = B_TRUE; 1353 1.3 chs 1354 1.3 chs rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg); 1355 1.3 chs if (!sdd->seenfrom) { 1356 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 1357 1.3 chs "WARNING: could not send %s@%s:\n" 1358 1.3 chs "incremental source (%s@%s) does not exist\n"), 1359 1.3 chs zhp->zfs_name, sdd->tosnap, 1360 1.3 chs zhp->zfs_name, sdd->fromsnap); 1361 1.3 chs sdd->err = B_TRUE; 1362 1.3 chs } else if (!sdd->seento) { 1363 1.3 chs if (sdd->fromsnap) { 1364 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 1365 1.1 haad "WARNING: could not send %s@%s:\n" 1366 1.3 chs "incremental source (%s@%s) " 1367 1.3 chs "is not earlier than it\n"), 1368 1.1 haad zhp->zfs_name, sdd->tosnap, 1369 1.1 haad zhp->zfs_name, sdd->fromsnap); 1370 1.1 haad } else { 1371 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 1372 1.3 chs "WARNING: " 1373 1.3 chs "could not send %s@%s: does not exist\n"), 1374 1.3 chs zhp->zfs_name, sdd->tosnap); 1375 1.1 haad } 1376 1.3 chs sdd->err = B_TRUE; 1377 1.1 haad } 1378 1.1 haad 1379 1.1 haad return (rv); 1380 1.1 haad } 1381 1.1 haad 1382 1.1 haad static int 1383 1.1 haad dump_filesystems(zfs_handle_t *rzhp, void *arg) 1384 1.1 haad { 1385 1.1 haad send_dump_data_t *sdd = arg; 1386 1.1 haad nvpair_t *fspair; 1387 1.1 haad boolean_t needagain, progress; 1388 1.1 haad 1389 1.1 haad if (!sdd->replicate) 1390 1.1 haad return (dump_filesystem(rzhp, sdd)); 1391 1.1 haad 1392 1.3 chs /* Mark the clone origin snapshots. */ 1393 1.3 chs for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair; 1394 1.3 chs fspair = nvlist_next_nvpair(sdd->fss, fspair)) { 1395 1.3 chs nvlist_t *nvfs; 1396 1.3 chs uint64_t origin_guid = 0; 1397 1.3 chs 1398 1.3 chs VERIFY(0 == nvpair_value_nvlist(fspair, &nvfs)); 1399 1.3 chs (void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid); 1400 1.3 chs if (origin_guid != 0) { 1401 1.3 chs char *snapname; 1402 1.3 chs nvlist_t *origin_nv = fsavl_find(sdd->fsavl, 1403 1.3 chs origin_guid, &snapname); 1404 1.3 chs if (origin_nv != NULL) { 1405 1.3 chs nvlist_t *snapprops; 1406 1.3 chs VERIFY(0 == nvlist_lookup_nvlist(origin_nv, 1407 1.3 chs "snapprops", &snapprops)); 1408 1.3 chs VERIFY(0 == nvlist_lookup_nvlist(snapprops, 1409 1.3 chs snapname, &snapprops)); 1410 1.3 chs VERIFY(0 == nvlist_add_boolean( 1411 1.3 chs snapprops, "is_clone_origin")); 1412 1.3 chs } 1413 1.3 chs } 1414 1.3 chs } 1415 1.1 haad again: 1416 1.1 haad needagain = progress = B_FALSE; 1417 1.1 haad for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair; 1418 1.1 haad fspair = nvlist_next_nvpair(sdd->fss, fspair)) { 1419 1.3 chs nvlist_t *fslist, *parent_nv; 1420 1.1 haad char *fsname; 1421 1.1 haad zfs_handle_t *zhp; 1422 1.1 haad int err; 1423 1.1 haad uint64_t origin_guid = 0; 1424 1.3 chs uint64_t parent_guid = 0; 1425 1.1 haad 1426 1.1 haad VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0); 1427 1.1 haad if (nvlist_lookup_boolean(fslist, "sent") == 0) 1428 1.1 haad continue; 1429 1.1 haad 1430 1.1 haad VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0); 1431 1.1 haad (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid); 1432 1.3 chs (void) nvlist_lookup_uint64(fslist, "parentfromsnap", 1433 1.3 chs &parent_guid); 1434 1.1 haad 1435 1.3 chs if (parent_guid != 0) { 1436 1.3 chs parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL); 1437 1.3 chs if (!nvlist_exists(parent_nv, "sent")) { 1438 1.3 chs /* parent has not been sent; skip this one */ 1439 1.3 chs needagain = B_TRUE; 1440 1.3 chs continue; 1441 1.3 chs } 1442 1.3 chs } 1443 1.3 chs 1444 1.3 chs if (origin_guid != 0) { 1445 1.3 chs nvlist_t *origin_nv = fsavl_find(sdd->fsavl, 1446 1.3 chs origin_guid, NULL); 1447 1.3 chs if (origin_nv != NULL && 1448 1.3 chs !nvlist_exists(origin_nv, "sent")) { 1449 1.3 chs /* 1450 1.3 chs * origin has not been sent yet; 1451 1.3 chs * skip this clone. 1452 1.3 chs */ 1453 1.3 chs needagain = B_TRUE; 1454 1.3 chs continue; 1455 1.3 chs } 1456 1.1 haad } 1457 1.1 haad 1458 1.1 haad zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET); 1459 1.1 haad if (zhp == NULL) 1460 1.1 haad return (-1); 1461 1.1 haad err = dump_filesystem(zhp, sdd); 1462 1.1 haad VERIFY(nvlist_add_boolean(fslist, "sent") == 0); 1463 1.1 haad progress = B_TRUE; 1464 1.1 haad zfs_close(zhp); 1465 1.1 haad if (err) 1466 1.1 haad return (err); 1467 1.1 haad } 1468 1.1 haad if (needagain) { 1469 1.1 haad assert(progress); 1470 1.1 haad goto again; 1471 1.1 haad } 1472 1.3 chs 1473 1.3 chs /* clean out the sent flags in case we reuse this fss */ 1474 1.3 chs for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair; 1475 1.3 chs fspair = nvlist_next_nvpair(sdd->fss, fspair)) { 1476 1.3 chs nvlist_t *fslist; 1477 1.3 chs 1478 1.3 chs VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0); 1479 1.3 chs (void) nvlist_remove_all(fslist, "sent"); 1480 1.3 chs } 1481 1.3 chs 1482 1.1 haad return (0); 1483 1.1 haad } 1484 1.1 haad 1485 1.3 chs nvlist_t * 1486 1.3 chs zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token) 1487 1.3 chs { 1488 1.3 chs unsigned int version; 1489 1.3 chs int nread; 1490 1.3 chs unsigned long long checksum, packed_len; 1491 1.3 chs 1492 1.3 chs /* 1493 1.3 chs * Decode token header, which is: 1494 1.3 chs * <token version>-<checksum of payload>-<uncompressed payload length> 1495 1.3 chs * Note that the only supported token version is 1. 1496 1.3 chs */ 1497 1.3 chs nread = sscanf(token, "%u-%llx-%llx-", 1498 1.3 chs &version, &checksum, &packed_len); 1499 1.3 chs if (nread != 3) { 1500 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1501 1.3 chs "resume token is corrupt (invalid format)")); 1502 1.3 chs return (NULL); 1503 1.3 chs } 1504 1.3 chs 1505 1.3 chs if (version != ZFS_SEND_RESUME_TOKEN_VERSION) { 1506 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1507 1.3 chs "resume token is corrupt (invalid version %u)"), 1508 1.3 chs version); 1509 1.3 chs return (NULL); 1510 1.3 chs } 1511 1.3 chs 1512 1.3 chs /* convert hexadecimal representation to binary */ 1513 1.3 chs token = strrchr(token, '-') + 1; 1514 1.3 chs int len = strlen(token) / 2; 1515 1.3 chs unsigned char *compressed = zfs_alloc(hdl, len); 1516 1.3 chs for (int i = 0; i < len; i++) { 1517 1.3 chs nread = sscanf(token + i * 2, "%2hhx", compressed + i); 1518 1.3 chs if (nread != 1) { 1519 1.3 chs free(compressed); 1520 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1521 1.3 chs "resume token is corrupt " 1522 1.3 chs "(payload is not hex-encoded)")); 1523 1.3 chs return (NULL); 1524 1.3 chs } 1525 1.3 chs } 1526 1.3 chs 1527 1.3 chs /* verify checksum */ 1528 1.3 chs zio_cksum_t cksum; 1529 1.3 chs fletcher_4_native(compressed, len, NULL, &cksum); 1530 1.3 chs if (cksum.zc_word[0] != checksum) { 1531 1.3 chs free(compressed); 1532 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1533 1.3 chs "resume token is corrupt (incorrect checksum)")); 1534 1.3 chs return (NULL); 1535 1.3 chs } 1536 1.3 chs 1537 1.3 chs /* uncompress */ 1538 1.3 chs void *packed = zfs_alloc(hdl, packed_len); 1539 1.3 chs uLongf packed_len_long = packed_len; 1540 1.3 chs if (uncompress(packed, &packed_len_long, compressed, len) != Z_OK || 1541 1.3 chs packed_len_long != packed_len) { 1542 1.3 chs free(packed); 1543 1.3 chs free(compressed); 1544 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1545 1.3 chs "resume token is corrupt (decompression failed)")); 1546 1.3 chs return (NULL); 1547 1.3 chs } 1548 1.3 chs 1549 1.3 chs /* unpack nvlist */ 1550 1.3 chs nvlist_t *nv; 1551 1.3 chs int error = nvlist_unpack(packed, packed_len, &nv, KM_SLEEP); 1552 1.3 chs free(packed); 1553 1.3 chs free(compressed); 1554 1.3 chs if (error != 0) { 1555 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1556 1.3 chs "resume token is corrupt (nvlist_unpack failed)")); 1557 1.3 chs return (NULL); 1558 1.3 chs } 1559 1.3 chs return (nv); 1560 1.3 chs } 1561 1.3 chs 1562 1.3 chs int 1563 1.3 chs zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd, 1564 1.3 chs const char *resume_token) 1565 1.3 chs { 1566 1.3 chs char errbuf[1024]; 1567 1.3 chs char *toname; 1568 1.3 chs char *fromname = NULL; 1569 1.3 chs uint64_t resumeobj, resumeoff, toguid, fromguid, bytes; 1570 1.3 chs zfs_handle_t *zhp; 1571 1.3 chs int error = 0; 1572 1.3 chs char name[ZFS_MAX_DATASET_NAME_LEN]; 1573 1.3 chs enum lzc_send_flags lzc_flags = 0; 1574 1.3 chs 1575 1.3 chs (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1576 1.3 chs "cannot resume send")); 1577 1.3 chs 1578 1.3 chs nvlist_t *resume_nvl = 1579 1.3 chs zfs_send_resume_token_to_nvlist(hdl, resume_token); 1580 1.3 chs if (resume_nvl == NULL) { 1581 1.3 chs /* 1582 1.3 chs * zfs_error_aux has already been set by 1583 1.3 chs * zfs_send_resume_token_to_nvlist 1584 1.3 chs */ 1585 1.3 chs return (zfs_error(hdl, EZFS_FAULT, errbuf)); 1586 1.3 chs } 1587 1.3 chs if (flags->verbose) { 1588 1.3 chs (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 1589 1.3 chs "resume token contents:\n")); 1590 1.3 chs nvlist_print(stderr, resume_nvl); 1591 1.3 chs } 1592 1.3 chs 1593 1.3 chs if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 || 1594 1.3 chs nvlist_lookup_uint64(resume_nvl, "object", &resumeobj) != 0 || 1595 1.3 chs nvlist_lookup_uint64(resume_nvl, "offset", &resumeoff) != 0 || 1596 1.3 chs nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 || 1597 1.3 chs nvlist_lookup_uint64(resume_nvl, "toguid", &toguid) != 0) { 1598 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1599 1.3 chs "resume token is corrupt")); 1600 1.3 chs return (zfs_error(hdl, EZFS_FAULT, errbuf)); 1601 1.3 chs } 1602 1.3 chs fromguid = 0; 1603 1.3 chs (void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid); 1604 1.3 chs 1605 1.3 chs if (flags->embed_data || nvlist_exists(resume_nvl, "embedok")) 1606 1.3 chs lzc_flags |= LZC_SEND_FLAG_EMBED_DATA; 1607 1.3 chs 1608 1.3 chs if (guid_to_name(hdl, toname, toguid, B_FALSE, name) != 0) { 1609 1.3 chs if (zfs_dataset_exists(hdl, toname, ZFS_TYPE_DATASET)) { 1610 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1611 1.3 chs "'%s' is no longer the same snapshot used in " 1612 1.3 chs "the initial send"), toname); 1613 1.3 chs } else { 1614 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1615 1.3 chs "'%s' used in the initial send no longer exists"), 1616 1.3 chs toname); 1617 1.3 chs } 1618 1.3 chs return (zfs_error(hdl, EZFS_BADPATH, errbuf)); 1619 1.3 chs } 1620 1.3 chs zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); 1621 1.3 chs if (zhp == NULL) { 1622 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1623 1.3 chs "unable to access '%s'"), name); 1624 1.3 chs return (zfs_error(hdl, EZFS_BADPATH, errbuf)); 1625 1.3 chs } 1626 1.3 chs 1627 1.3 chs if (fromguid != 0) { 1628 1.3 chs if (guid_to_name(hdl, toname, fromguid, B_TRUE, name) != 0) { 1629 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1630 1.3 chs "incremental source %#llx no longer exists"), 1631 1.3 chs (longlong_t)fromguid); 1632 1.3 chs return (zfs_error(hdl, EZFS_BADPATH, errbuf)); 1633 1.3 chs } 1634 1.3 chs fromname = name; 1635 1.3 chs } 1636 1.3 chs 1637 1.3 chs if (flags->verbose) { 1638 1.3 chs uint64_t size = 0; 1639 1.3 chs error = lzc_send_space(zhp->zfs_name, fromname, &size); 1640 1.3 chs if (error == 0) 1641 1.3 chs size = MAX(0, (int64_t)(size - bytes)); 1642 1.3 chs send_print_verbose(stderr, zhp->zfs_name, fromname, 1643 1.3 chs size, flags->parsable); 1644 1.3 chs } 1645 1.3 chs 1646 1.3 chs if (!flags->dryrun) { 1647 1.3 chs progress_arg_t pa = { 0 }; 1648 1.3 chs pthread_t tid; 1649 1.3 chs /* 1650 1.3 chs * If progress reporting is requested, spawn a new thread to 1651 1.3 chs * poll ZFS_IOC_SEND_PROGRESS at a regular interval. 1652 1.3 chs */ 1653 1.3 chs if (flags->progress) { 1654 1.3 chs pa.pa_zhp = zhp; 1655 1.3 chs pa.pa_fd = outfd; 1656 1.3 chs pa.pa_parsable = flags->parsable; 1657 1.3 chs 1658 1.3 chs error = pthread_create(&tid, NULL, 1659 1.3 chs send_progress_thread, &pa); 1660 1.3 chs if (error != 0) { 1661 1.3 chs zfs_close(zhp); 1662 1.3 chs return (error); 1663 1.3 chs } 1664 1.3 chs } 1665 1.3 chs 1666 1.3 chs error = lzc_send_resume(zhp->zfs_name, fromname, outfd, 1667 1.3 chs lzc_flags, resumeobj, resumeoff); 1668 1.3 chs 1669 1.3 chs if (flags->progress) { 1670 1.3 chs (void) pthread_cancel(tid); 1671 1.3 chs (void) pthread_join(tid, NULL); 1672 1.3 chs } 1673 1.3 chs 1674 1.3 chs char errbuf[1024]; 1675 1.3 chs (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1676 1.3 chs "warning: cannot send '%s'"), zhp->zfs_name); 1677 1.3 chs 1678 1.3 chs zfs_close(zhp); 1679 1.3 chs 1680 1.3 chs switch (error) { 1681 1.3 chs case 0: 1682 1.3 chs return (0); 1683 1.3 chs case EXDEV: 1684 1.3 chs case ENOENT: 1685 1.3 chs case EDQUOT: 1686 1.3 chs case EFBIG: 1687 1.3 chs case EIO: 1688 1.3 chs case ENOLINK: 1689 1.3 chs case ENOSPC: 1690 1.3 chs #ifdef illumos 1691 1.3 chs case ENOSTR: 1692 1.3 chs #endif 1693 1.3 chs case ENXIO: 1694 1.3 chs case EPIPE: 1695 1.3 chs case ERANGE: 1696 1.3 chs case EFAULT: 1697 1.3 chs case EROFS: 1698 1.3 chs zfs_error_aux(hdl, strerror(errno)); 1699 1.3 chs return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); 1700 1.3 chs 1701 1.3 chs default: 1702 1.3 chs return (zfs_standard_error(hdl, errno, errbuf)); 1703 1.3 chs } 1704 1.3 chs } 1705 1.3 chs 1706 1.3 chs 1707 1.3 chs zfs_close(zhp); 1708 1.3 chs 1709 1.3 chs return (error); 1710 1.3 chs } 1711 1.3 chs 1712 1.1 haad /* 1713 1.2 dsl * Generate a send stream for the dataset identified by the argument zhp. 1714 1.2 dsl * 1715 1.2 dsl * The content of the send stream is the snapshot identified by 1716 1.2 dsl * 'tosnap'. Incremental streams are requested in two ways: 1717 1.2 dsl * - from the snapshot identified by "fromsnap" (if non-null) or 1718 1.2 dsl * - from the origin of the dataset identified by zhp, which must 1719 1.2 dsl * be a clone. In this case, "fromsnap" is null and "fromorigin" 1720 1.2 dsl * is TRUE. 1721 1.2 dsl * 1722 1.2 dsl * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and 1723 1.2 dsl * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM) 1724 1.2 dsl * if "replicate" is set. If "doall" is set, dump all the intermediate 1725 1.2 dsl * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall" 1726 1.2 dsl * case too. If "props" is set, send properties. 1727 1.1 haad */ 1728 1.1 haad int 1729 1.1 haad zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, 1730 1.3 chs sendflags_t *flags, int outfd, snapfilter_cb_t filter_func, 1731 1.3 chs void *cb_arg, nvlist_t **debugnvp) 1732 1.1 haad { 1733 1.1 haad char errbuf[1024]; 1734 1.1 haad send_dump_data_t sdd = { 0 }; 1735 1.3 chs int err = 0; 1736 1.1 haad nvlist_t *fss = NULL; 1737 1.1 haad avl_tree_t *fsavl = NULL; 1738 1.2 dsl static uint64_t holdseq; 1739 1.2 dsl int spa_version; 1740 1.3 chs pthread_t tid = 0; 1741 1.2 dsl int pipefd[2]; 1742 1.2 dsl dedup_arg_t dda = { 0 }; 1743 1.2 dsl int featureflags = 0; 1744 1.3 chs FILE *fout; 1745 1.1 haad 1746 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1747 1.1 haad "cannot send '%s'"), zhp->zfs_name); 1748 1.1 haad 1749 1.1 haad if (fromsnap && fromsnap[0] == '\0') { 1750 1.1 haad zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, 1751 1.1 haad "zero-length incremental source")); 1752 1.1 haad return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf)); 1753 1.1 haad } 1754 1.1 haad 1755 1.3 chs if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM) { 1756 1.3 chs uint64_t version; 1757 1.3 chs version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION); 1758 1.3 chs if (version >= ZPL_VERSION_SA) { 1759 1.3 chs featureflags |= DMU_BACKUP_FEATURE_SA_SPILL; 1760 1.3 chs } 1761 1.3 chs } 1762 1.2 dsl 1763 1.3 chs if (flags->dedup && !flags->dryrun) { 1764 1.2 dsl featureflags |= (DMU_BACKUP_FEATURE_DEDUP | 1765 1.2 dsl DMU_BACKUP_FEATURE_DEDUPPROPS); 1766 1.3 chs if ((err = pipe(pipefd)) != 0) { 1767 1.2 dsl zfs_error_aux(zhp->zfs_hdl, strerror(errno)); 1768 1.2 dsl return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, 1769 1.2 dsl errbuf)); 1770 1.2 dsl } 1771 1.2 dsl dda.outputfd = outfd; 1772 1.2 dsl dda.inputfd = pipefd[1]; 1773 1.2 dsl dda.dedup_hdl = zhp->zfs_hdl; 1774 1.3 chs if ((err = pthread_create(&tid, NULL, cksummer, &dda)) != 0) { 1775 1.2 dsl (void) close(pipefd[0]); 1776 1.2 dsl (void) close(pipefd[1]); 1777 1.2 dsl zfs_error_aux(zhp->zfs_hdl, strerror(errno)); 1778 1.2 dsl return (zfs_error(zhp->zfs_hdl, 1779 1.2 dsl EZFS_THREADCREATEFAILED, errbuf)); 1780 1.2 dsl } 1781 1.2 dsl } 1782 1.2 dsl 1783 1.3 chs if (flags->replicate || flags->doall || flags->props) { 1784 1.1 haad dmu_replay_record_t drr = { 0 }; 1785 1.1 haad char *packbuf = NULL; 1786 1.1 haad size_t buflen = 0; 1787 1.1 haad zio_cksum_t zc = { 0 }; 1788 1.1 haad 1789 1.3 chs if (flags->replicate || flags->props) { 1790 1.1 haad nvlist_t *hdrnv; 1791 1.1 haad 1792 1.1 haad VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0)); 1793 1.1 haad if (fromsnap) { 1794 1.1 haad VERIFY(0 == nvlist_add_string(hdrnv, 1795 1.1 haad "fromsnap", fromsnap)); 1796 1.1 haad } 1797 1.1 haad VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap)); 1798 1.3 chs if (!flags->replicate) { 1799 1.2 dsl VERIFY(0 == nvlist_add_boolean(hdrnv, 1800 1.2 dsl "not_recursive")); 1801 1.2 dsl } 1802 1.1 haad 1803 1.1 haad err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name, 1804 1.3 chs fromsnap, tosnap, flags->replicate, flags->verbose, 1805 1.3 chs &fss, &fsavl); 1806 1.3 chs if (err) 1807 1.2 dsl goto err_out; 1808 1.1 haad VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss)); 1809 1.1 haad err = nvlist_pack(hdrnv, &packbuf, &buflen, 1810 1.1 haad NV_ENCODE_XDR, 0); 1811 1.3 chs if (debugnvp) 1812 1.3 chs *debugnvp = hdrnv; 1813 1.3 chs else 1814 1.3 chs nvlist_free(hdrnv); 1815 1.3 chs if (err) 1816 1.2 dsl goto stderr_out; 1817 1.1 haad } 1818 1.1 haad 1819 1.3 chs if (!flags->dryrun) { 1820 1.3 chs /* write first begin record */ 1821 1.3 chs drr.drr_type = DRR_BEGIN; 1822 1.3 chs drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC; 1823 1.3 chs DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin. 1824 1.3 chs drr_versioninfo, DMU_COMPOUNDSTREAM); 1825 1.3 chs DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin. 1826 1.3 chs drr_versioninfo, featureflags); 1827 1.3 chs (void) snprintf(drr.drr_u.drr_begin.drr_toname, 1828 1.3 chs sizeof (drr.drr_u.drr_begin.drr_toname), 1829 1.3 chs "%s@%s", zhp->zfs_name, tosnap); 1830 1.3 chs drr.drr_payloadlen = buflen; 1831 1.3 chs 1832 1.3 chs err = dump_record(&drr, packbuf, buflen, &zc, outfd); 1833 1.3 chs free(packbuf); 1834 1.3 chs if (err != 0) 1835 1.3 chs goto stderr_out; 1836 1.1 haad 1837 1.3 chs /* write end record */ 1838 1.1 haad bzero(&drr, sizeof (drr)); 1839 1.1 haad drr.drr_type = DRR_END; 1840 1.1 haad drr.drr_u.drr_end.drr_checksum = zc; 1841 1.1 haad err = write(outfd, &drr, sizeof (drr)); 1842 1.1 haad if (err == -1) { 1843 1.2 dsl err = errno; 1844 1.2 dsl goto stderr_out; 1845 1.1 haad } 1846 1.3 chs 1847 1.3 chs err = 0; 1848 1.1 haad } 1849 1.1 haad } 1850 1.1 haad 1851 1.1 haad /* dump each stream */ 1852 1.1 haad sdd.fromsnap = fromsnap; 1853 1.1 haad sdd.tosnap = tosnap; 1854 1.3 chs if (tid != 0) 1855 1.2 dsl sdd.outfd = pipefd[0]; 1856 1.2 dsl else 1857 1.2 dsl sdd.outfd = outfd; 1858 1.3 chs sdd.replicate = flags->replicate; 1859 1.3 chs sdd.doall = flags->doall; 1860 1.3 chs sdd.fromorigin = flags->fromorigin; 1861 1.1 haad sdd.fss = fss; 1862 1.1 haad sdd.fsavl = fsavl; 1863 1.3 chs sdd.verbose = flags->verbose; 1864 1.3 chs sdd.parsable = flags->parsable; 1865 1.3 chs sdd.progress = flags->progress; 1866 1.3 chs sdd.dryrun = flags->dryrun; 1867 1.3 chs sdd.large_block = flags->largeblock; 1868 1.3 chs sdd.embed_data = flags->embed_data; 1869 1.2 dsl sdd.filter_cb = filter_func; 1870 1.2 dsl sdd.filter_cb_arg = cb_arg; 1871 1.3 chs if (debugnvp) 1872 1.3 chs sdd.debugnv = *debugnvp; 1873 1.3 chs if (sdd.verbose && sdd.dryrun) 1874 1.3 chs sdd.std_out = B_TRUE; 1875 1.3 chs fout = sdd.std_out ? stdout : stderr; 1876 1.3 chs 1877 1.3 chs /* 1878 1.3 chs * Some flags require that we place user holds on the datasets that are 1879 1.3 chs * being sent so they don't get destroyed during the send. We can skip 1880 1.3 chs * this step if the pool is imported read-only since the datasets cannot 1881 1.3 chs * be destroyed. 1882 1.3 chs */ 1883 1.3 chs if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp), 1884 1.3 chs ZPOOL_PROP_READONLY, NULL) && 1885 1.3 chs zfs_spa_version(zhp, &spa_version) == 0 && 1886 1.3 chs spa_version >= SPA_VERSION_USERREFS && 1887 1.3 chs (flags->doall || flags->replicate)) { 1888 1.3 chs ++holdseq; 1889 1.3 chs (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag), 1890 1.3 chs ".send-%d-%llu", getpid(), (u_longlong_t)holdseq); 1891 1.3 chs sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL); 1892 1.3 chs if (sdd.cleanup_fd < 0) { 1893 1.3 chs err = errno; 1894 1.3 chs goto stderr_out; 1895 1.3 chs } 1896 1.3 chs sdd.snapholds = fnvlist_alloc(); 1897 1.3 chs } else { 1898 1.3 chs sdd.cleanup_fd = -1; 1899 1.3 chs sdd.snapholds = NULL; 1900 1.3 chs } 1901 1.3 chs if (flags->verbose || sdd.snapholds != NULL) { 1902 1.3 chs /* 1903 1.3 chs * Do a verbose no-op dry run to get all the verbose output 1904 1.3 chs * or to gather snapshot hold's before generating any data, 1905 1.3 chs * then do a non-verbose real run to generate the streams. 1906 1.3 chs */ 1907 1.3 chs sdd.dryrun = B_TRUE; 1908 1.3 chs err = dump_filesystems(zhp, &sdd); 1909 1.3 chs 1910 1.3 chs if (err != 0) 1911 1.3 chs goto stderr_out; 1912 1.3 chs 1913 1.3 chs if (flags->verbose) { 1914 1.3 chs if (flags->parsable) { 1915 1.3 chs (void) fprintf(fout, "size\t%llu\n", 1916 1.3 chs (longlong_t)sdd.size); 1917 1.3 chs } else { 1918 1.3 chs char buf[16]; 1919 1.3 chs zfs_nicenum(sdd.size, buf, sizeof (buf)); 1920 1.3 chs (void) fprintf(fout, dgettext(TEXT_DOMAIN, 1921 1.3 chs "total estimated size is %s\n"), buf); 1922 1.3 chs } 1923 1.3 chs } 1924 1.3 chs 1925 1.3 chs /* Ensure no snaps found is treated as an error. */ 1926 1.3 chs if (!sdd.seento) { 1927 1.3 chs err = ENOENT; 1928 1.3 chs goto err_out; 1929 1.3 chs } 1930 1.3 chs 1931 1.3 chs /* Skip the second run if dryrun was requested. */ 1932 1.3 chs if (flags->dryrun) 1933 1.3 chs goto err_out; 1934 1.3 chs 1935 1.3 chs if (sdd.snapholds != NULL) { 1936 1.3 chs err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds); 1937 1.3 chs if (err != 0) 1938 1.3 chs goto stderr_out; 1939 1.3 chs 1940 1.3 chs fnvlist_free(sdd.snapholds); 1941 1.3 chs sdd.snapholds = NULL; 1942 1.3 chs } 1943 1.3 chs 1944 1.3 chs sdd.dryrun = B_FALSE; 1945 1.3 chs sdd.verbose = B_FALSE; 1946 1.3 chs } 1947 1.3 chs 1948 1.1 haad err = dump_filesystems(zhp, &sdd); 1949 1.1 haad fsavl_destroy(fsavl); 1950 1.1 haad nvlist_free(fss); 1951 1.1 haad 1952 1.3 chs /* Ensure no snaps found is treated as an error. */ 1953 1.3 chs if (err == 0 && !sdd.seento) 1954 1.3 chs err = ENOENT; 1955 1.3 chs 1956 1.3 chs if (tid != 0) { 1957 1.3 chs if (err != 0) 1958 1.3 chs (void) pthread_cancel(tid); 1959 1.2 dsl (void) close(pipefd[0]); 1960 1.2 dsl (void) pthread_join(tid, NULL); 1961 1.2 dsl } 1962 1.2 dsl 1963 1.3 chs if (sdd.cleanup_fd != -1) { 1964 1.3 chs VERIFY(0 == close(sdd.cleanup_fd)); 1965 1.3 chs sdd.cleanup_fd = -1; 1966 1.3 chs } 1967 1.3 chs 1968 1.3 chs if (!flags->dryrun && (flags->replicate || flags->doall || 1969 1.3 chs flags->props)) { 1970 1.1 haad /* 1971 1.1 haad * write final end record. NB: want to do this even if 1972 1.1 haad * there was some error, because it might not be totally 1973 1.1 haad * failed. 1974 1.1 haad */ 1975 1.1 haad dmu_replay_record_t drr = { 0 }; 1976 1.1 haad drr.drr_type = DRR_END; 1977 1.1 haad if (write(outfd, &drr, sizeof (drr)) == -1) { 1978 1.1 haad return (zfs_standard_error(zhp->zfs_hdl, 1979 1.1 haad errno, errbuf)); 1980 1.1 haad } 1981 1.1 haad } 1982 1.1 haad 1983 1.1 haad return (err || sdd.err); 1984 1.2 dsl 1985 1.2 dsl stderr_out: 1986 1.2 dsl err = zfs_standard_error(zhp->zfs_hdl, err, errbuf); 1987 1.2 dsl err_out: 1988 1.3 chs fsavl_destroy(fsavl); 1989 1.3 chs nvlist_free(fss); 1990 1.3 chs fnvlist_free(sdd.snapholds); 1991 1.3 chs 1992 1.3 chs if (sdd.cleanup_fd != -1) 1993 1.3 chs VERIFY(0 == close(sdd.cleanup_fd)); 1994 1.3 chs if (tid != 0) { 1995 1.2 dsl (void) pthread_cancel(tid); 1996 1.3 chs (void) close(pipefd[0]); 1997 1.2 dsl (void) pthread_join(tid, NULL); 1998 1.2 dsl } 1999 1.2 dsl return (err); 2000 1.1 haad } 2001 1.1 haad 2002 1.3 chs int 2003 1.3 chs zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, 2004 1.3 chs enum lzc_send_flags flags) 2005 1.3 chs { 2006 1.3 chs int err; 2007 1.3 chs libzfs_handle_t *hdl = zhp->zfs_hdl; 2008 1.3 chs 2009 1.3 chs char errbuf[1024]; 2010 1.3 chs (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2011 1.3 chs "warning: cannot send '%s'"), zhp->zfs_name); 2012 1.3 chs 2013 1.3 chs err = lzc_send(zhp->zfs_name, from, fd, flags); 2014 1.3 chs if (err != 0) { 2015 1.3 chs switch (errno) { 2016 1.3 chs case EXDEV: 2017 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2018 1.3 chs "not an earlier snapshot from the same fs")); 2019 1.3 chs return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf)); 2020 1.3 chs 2021 1.3 chs case ENOENT: 2022 1.3 chs case ESRCH: 2023 1.3 chs if (lzc_exists(zhp->zfs_name)) { 2024 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2025 1.3 chs "incremental source (%s) does not exist"), 2026 1.3 chs from); 2027 1.3 chs } 2028 1.3 chs return (zfs_error(hdl, EZFS_NOENT, errbuf)); 2029 1.3 chs 2030 1.3 chs case EBUSY: 2031 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2032 1.3 chs "target is busy; if a filesystem, " 2033 1.3 chs "it must not be mounted")); 2034 1.3 chs return (zfs_error(hdl, EZFS_BUSY, errbuf)); 2035 1.3 chs 2036 1.3 chs case EDQUOT: 2037 1.3 chs case EFBIG: 2038 1.3 chs case EIO: 2039 1.3 chs case ENOLINK: 2040 1.3 chs case ENOSPC: 2041 1.3 chs #ifdef illumos 2042 1.3 chs case ENOSTR: 2043 1.3 chs #endif 2044 1.3 chs case ENXIO: 2045 1.3 chs case EPIPE: 2046 1.3 chs case ERANGE: 2047 1.3 chs case EFAULT: 2048 1.3 chs case EROFS: 2049 1.3 chs zfs_error_aux(hdl, strerror(errno)); 2050 1.3 chs return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); 2051 1.3 chs 2052 1.3 chs default: 2053 1.3 chs return (zfs_standard_error(hdl, errno, errbuf)); 2054 1.3 chs } 2055 1.3 chs } 2056 1.3 chs return (err != 0); 2057 1.3 chs } 2058 1.3 chs 2059 1.1 haad /* 2060 1.1 haad * Routines specific to "zfs recv" 2061 1.1 haad */ 2062 1.1 haad 2063 1.1 haad static int 2064 1.1 haad recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen, 2065 1.1 haad boolean_t byteswap, zio_cksum_t *zc) 2066 1.1 haad { 2067 1.1 haad char *cp = buf; 2068 1.1 haad int rv; 2069 1.1 haad int len = ilen; 2070 1.1 haad 2071 1.3 chs assert(ilen <= SPA_MAXBLOCKSIZE); 2072 1.3 chs 2073 1.1 haad do { 2074 1.1 haad rv = read(fd, cp, len); 2075 1.1 haad cp += rv; 2076 1.1 haad len -= rv; 2077 1.1 haad } while (rv > 0); 2078 1.1 haad 2079 1.1 haad if (rv < 0 || len != 0) { 2080 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2081 1.1 haad "failed to read from stream")); 2082 1.1 haad return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN, 2083 1.1 haad "cannot receive"))); 2084 1.1 haad } 2085 1.1 haad 2086 1.1 haad if (zc) { 2087 1.1 haad if (byteswap) 2088 1.1 haad fletcher_4_incremental_byteswap(buf, ilen, zc); 2089 1.1 haad else 2090 1.1 haad fletcher_4_incremental_native(buf, ilen, zc); 2091 1.1 haad } 2092 1.1 haad return (0); 2093 1.1 haad } 2094 1.1 haad 2095 1.1 haad static int 2096 1.1 haad recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp, 2097 1.1 haad boolean_t byteswap, zio_cksum_t *zc) 2098 1.1 haad { 2099 1.1 haad char *buf; 2100 1.1 haad int err; 2101 1.1 haad 2102 1.1 haad buf = zfs_alloc(hdl, len); 2103 1.1 haad if (buf == NULL) 2104 1.1 haad return (ENOMEM); 2105 1.1 haad 2106 1.1 haad err = recv_read(hdl, fd, buf, len, byteswap, zc); 2107 1.1 haad if (err != 0) { 2108 1.1 haad free(buf); 2109 1.1 haad return (err); 2110 1.1 haad } 2111 1.1 haad 2112 1.1 haad err = nvlist_unpack(buf, len, nvp, 0); 2113 1.1 haad free(buf); 2114 1.1 haad if (err != 0) { 2115 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 2116 1.1 haad "stream (malformed nvlist)")); 2117 1.1 haad return (EINVAL); 2118 1.1 haad } 2119 1.1 haad return (0); 2120 1.1 haad } 2121 1.1 haad 2122 1.1 haad static int 2123 1.1 haad recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname, 2124 1.3 chs int baselen, char *newname, recvflags_t *flags) 2125 1.1 haad { 2126 1.1 haad static int seq; 2127 1.1 haad zfs_cmd_t zc = { 0 }; 2128 1.1 haad int err; 2129 1.1 haad prop_changelist_t *clp; 2130 1.1 haad zfs_handle_t *zhp; 2131 1.1 haad 2132 1.1 haad zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); 2133 1.1 haad if (zhp == NULL) 2134 1.1 haad return (-1); 2135 1.1 haad clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 2136 1.3 chs flags->force ? MS_FORCE : 0); 2137 1.1 haad zfs_close(zhp); 2138 1.1 haad if (clp == NULL) 2139 1.1 haad return (-1); 2140 1.1 haad err = changelist_prefix(clp); 2141 1.1 haad if (err) 2142 1.1 haad return (err); 2143 1.1 haad 2144 1.2 dsl zc.zc_objset_type = DMU_OST_ZFS; 2145 1.2 dsl (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name)); 2146 1.2 dsl 2147 1.1 haad if (tryname) { 2148 1.1 haad (void) strcpy(newname, tryname); 2149 1.1 haad 2150 1.1 haad (void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value)); 2151 1.1 haad 2152 1.3 chs if (flags->verbose) { 2153 1.1 haad (void) printf("attempting rename %s to %s\n", 2154 1.1 haad zc.zc_name, zc.zc_value); 2155 1.1 haad } 2156 1.1 haad err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc); 2157 1.1 haad if (err == 0) 2158 1.1 haad changelist_rename(clp, name, tryname); 2159 1.1 haad } else { 2160 1.1 haad err = ENOENT; 2161 1.1 haad } 2162 1.1 haad 2163 1.3 chs if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) { 2164 1.1 haad seq++; 2165 1.1 haad 2166 1.3 chs (void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN, 2167 1.3 chs "%.*srecv-%u-%u", baselen, name, getpid(), seq); 2168 1.1 haad (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value)); 2169 1.1 haad 2170 1.3 chs if (flags->verbose) { 2171 1.1 haad (void) printf("failed - trying rename %s to %s\n", 2172 1.1 haad zc.zc_name, zc.zc_value); 2173 1.1 haad } 2174 1.1 haad err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc); 2175 1.1 haad if (err == 0) 2176 1.1 haad changelist_rename(clp, name, newname); 2177 1.3 chs if (err && flags->verbose) { 2178 1.1 haad (void) printf("failed (%u) - " 2179 1.1 haad "will try again on next pass\n", errno); 2180 1.1 haad } 2181 1.1 haad err = EAGAIN; 2182 1.3 chs } else if (flags->verbose) { 2183 1.1 haad if (err == 0) 2184 1.1 haad (void) printf("success\n"); 2185 1.1 haad else 2186 1.1 haad (void) printf("failed (%u)\n", errno); 2187 1.1 haad } 2188 1.1 haad 2189 1.1 haad (void) changelist_postfix(clp); 2190 1.1 haad changelist_free(clp); 2191 1.1 haad 2192 1.1 haad return (err); 2193 1.1 haad } 2194 1.1 haad 2195 1.1 haad static int 2196 1.1 haad recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen, 2197 1.3 chs char *newname, recvflags_t *flags) 2198 1.1 haad { 2199 1.1 haad zfs_cmd_t zc = { 0 }; 2200 1.1 haad int err = 0; 2201 1.1 haad prop_changelist_t *clp; 2202 1.1 haad zfs_handle_t *zhp; 2203 1.2 dsl boolean_t defer = B_FALSE; 2204 1.2 dsl int spa_version; 2205 1.1 haad 2206 1.1 haad zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); 2207 1.1 haad if (zhp == NULL) 2208 1.1 haad return (-1); 2209 1.1 haad clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 2210 1.3 chs flags->force ? MS_FORCE : 0); 2211 1.2 dsl if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT && 2212 1.2 dsl zfs_spa_version(zhp, &spa_version) == 0 && 2213 1.2 dsl spa_version >= SPA_VERSION_USERREFS) 2214 1.2 dsl defer = B_TRUE; 2215 1.1 haad zfs_close(zhp); 2216 1.1 haad if (clp == NULL) 2217 1.1 haad return (-1); 2218 1.1 haad err = changelist_prefix(clp); 2219 1.1 haad if (err) 2220 1.1 haad return (err); 2221 1.1 haad 2222 1.1 haad zc.zc_objset_type = DMU_OST_ZFS; 2223 1.2 dsl zc.zc_defer_destroy = defer; 2224 1.1 haad (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name)); 2225 1.1 haad 2226 1.3 chs if (flags->verbose) 2227 1.1 haad (void) printf("attempting destroy %s\n", zc.zc_name); 2228 1.1 haad err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc); 2229 1.1 haad if (err == 0) { 2230 1.3 chs if (flags->verbose) 2231 1.1 haad (void) printf("success\n"); 2232 1.1 haad changelist_remove(clp, zc.zc_name); 2233 1.1 haad } 2234 1.1 haad 2235 1.1 haad (void) changelist_postfix(clp); 2236 1.1 haad changelist_free(clp); 2237 1.1 haad 2238 1.2 dsl /* 2239 1.2 dsl * Deferred destroy might destroy the snapshot or only mark it to be 2240 1.2 dsl * destroyed later, and it returns success in either case. 2241 1.2 dsl */ 2242 1.2 dsl if (err != 0 || (defer && zfs_dataset_exists(hdl, name, 2243 1.2 dsl ZFS_TYPE_SNAPSHOT))) { 2244 1.1 haad err = recv_rename(hdl, name, NULL, baselen, newname, flags); 2245 1.2 dsl } 2246 1.1 haad 2247 1.1 haad return (err); 2248 1.1 haad } 2249 1.1 haad 2250 1.1 haad typedef struct guid_to_name_data { 2251 1.1 haad uint64_t guid; 2252 1.3 chs boolean_t bookmark_ok; 2253 1.1 haad char *name; 2254 1.3 chs char *skip; 2255 1.1 haad } guid_to_name_data_t; 2256 1.1 haad 2257 1.1 haad static int 2258 1.1 haad guid_to_name_cb(zfs_handle_t *zhp, void *arg) 2259 1.1 haad { 2260 1.1 haad guid_to_name_data_t *gtnd = arg; 2261 1.3 chs const char *slash; 2262 1.1 haad int err; 2263 1.1 haad 2264 1.3 chs if (gtnd->skip != NULL && 2265 1.3 chs (slash = strrchr(zhp->zfs_name, '/')) != NULL && 2266 1.3 chs strcmp(slash + 1, gtnd->skip) == 0) { 2267 1.3 chs zfs_close(zhp); 2268 1.3 chs return (0); 2269 1.3 chs } 2270 1.3 chs 2271 1.3 chs if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid) { 2272 1.1 haad (void) strcpy(gtnd->name, zhp->zfs_name); 2273 1.2 dsl zfs_close(zhp); 2274 1.1 haad return (EEXIST); 2275 1.1 haad } 2276 1.3 chs 2277 1.1 haad err = zfs_iter_children(zhp, guid_to_name_cb, gtnd); 2278 1.3 chs if (err != EEXIST && gtnd->bookmark_ok) 2279 1.3 chs err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd); 2280 1.1 haad zfs_close(zhp); 2281 1.1 haad return (err); 2282 1.1 haad } 2283 1.1 haad 2284 1.3 chs /* 2285 1.3 chs * Attempt to find the local dataset associated with this guid. In the case of 2286 1.3 chs * multiple matches, we attempt to find the "best" match by searching 2287 1.3 chs * progressively larger portions of the hierarchy. This allows one to send a 2288 1.3 chs * tree of datasets individually and guarantee that we will find the source 2289 1.3 chs * guid within that hierarchy, even if there are multiple matches elsewhere. 2290 1.3 chs */ 2291 1.1 haad static int 2292 1.1 haad guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid, 2293 1.3 chs boolean_t bookmark_ok, char *name) 2294 1.1 haad { 2295 1.3 chs char pname[ZFS_MAX_DATASET_NAME_LEN]; 2296 1.1 haad guid_to_name_data_t gtnd; 2297 1.1 haad 2298 1.1 haad gtnd.guid = guid; 2299 1.3 chs gtnd.bookmark_ok = bookmark_ok; 2300 1.1 haad gtnd.name = name; 2301 1.3 chs gtnd.skip = NULL; 2302 1.1 haad 2303 1.3 chs /* 2304 1.3 chs * Search progressively larger portions of the hierarchy, starting 2305 1.3 chs * with the filesystem specified by 'parent'. This will 2306 1.3 chs * select the "most local" version of the origin snapshot in the case 2307 1.3 chs * that there are multiple matching snapshots in the system. 2308 1.3 chs */ 2309 1.3 chs (void) strlcpy(pname, parent, sizeof (pname)); 2310 1.3 chs char *cp = strrchr(pname, '@'); 2311 1.3 chs if (cp == NULL) 2312 1.3 chs cp = strchr(pname, '\0'); 2313 1.3 chs for (; cp != NULL; cp = strrchr(pname, '/')) { 2314 1.3 chs /* Chop off the last component and open the parent */ 2315 1.1 haad *cp = '\0'; 2316 1.3 chs zfs_handle_t *zhp = make_dataset_handle(hdl, pname); 2317 1.1 haad 2318 1.3 chs if (zhp == NULL) 2319 1.3 chs continue; 2320 1.3 chs int err = guid_to_name_cb(zfs_handle_dup(zhp), >nd); 2321 1.3 chs if (err != EEXIST) 2322 1.3 chs err = zfs_iter_children(zhp, guid_to_name_cb, >nd); 2323 1.3 chs if (err != EEXIST && bookmark_ok) 2324 1.3 chs err = zfs_iter_bookmarks(zhp, guid_to_name_cb, >nd); 2325 1.1 haad zfs_close(zhp); 2326 1.3 chs if (err == EEXIST) 2327 1.3 chs return (0); 2328 1.3 chs 2329 1.3 chs /* 2330 1.3 chs * Remember the last portion of the dataset so we skip it next 2331 1.3 chs * time through (as we've already searched that portion of the 2332 1.3 chs * hierarchy). 2333 1.3 chs */ 2334 1.3 chs gtnd.skip = strrchr(pname, '/') + 1; 2335 1.1 haad } 2336 1.1 haad 2337 1.3 chs return (ENOENT); 2338 1.1 haad } 2339 1.1 haad 2340 1.1 haad /* 2341 1.3 chs * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if 2342 1.3 chs * guid1 is after guid2. 2343 1.1 haad */ 2344 1.1 haad static int 2345 1.1 haad created_before(libzfs_handle_t *hdl, avl_tree_t *avl, 2346 1.1 haad uint64_t guid1, uint64_t guid2) 2347 1.1 haad { 2348 1.1 haad nvlist_t *nvfs; 2349 1.1 haad char *fsname, *snapname; 2350 1.3 chs char buf[ZFS_MAX_DATASET_NAME_LEN]; 2351 1.1 haad int rv; 2352 1.3 chs zfs_handle_t *guid1hdl, *guid2hdl; 2353 1.3 chs uint64_t create1, create2; 2354 1.1 haad 2355 1.1 haad if (guid2 == 0) 2356 1.1 haad return (0); 2357 1.1 haad if (guid1 == 0) 2358 1.1 haad return (1); 2359 1.1 haad 2360 1.1 haad nvfs = fsavl_find(avl, guid1, &snapname); 2361 1.1 haad VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname)); 2362 1.1 haad (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname); 2363 1.3 chs guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT); 2364 1.3 chs if (guid1hdl == NULL) 2365 1.1 haad return (-1); 2366 1.1 haad 2367 1.1 haad nvfs = fsavl_find(avl, guid2, &snapname); 2368 1.1 haad VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname)); 2369 1.1 haad (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname); 2370 1.3 chs guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT); 2371 1.3 chs if (guid2hdl == NULL) { 2372 1.3 chs zfs_close(guid1hdl); 2373 1.1 haad return (-1); 2374 1.1 haad } 2375 1.1 haad 2376 1.3 chs create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG); 2377 1.3 chs create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG); 2378 1.3 chs 2379 1.3 chs if (create1 < create2) 2380 1.3 chs rv = -1; 2381 1.3 chs else if (create1 > create2) 2382 1.3 chs rv = +1; 2383 1.3 chs else 2384 1.3 chs rv = 0; 2385 1.1 haad 2386 1.3 chs zfs_close(guid1hdl); 2387 1.3 chs zfs_close(guid2hdl); 2388 1.1 haad 2389 1.1 haad return (rv); 2390 1.1 haad } 2391 1.1 haad 2392 1.1 haad static int 2393 1.1 haad recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs, 2394 1.3 chs recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl, 2395 1.3 chs nvlist_t *renamed) 2396 1.1 haad { 2397 1.3 chs nvlist_t *local_nv, *deleted = NULL; 2398 1.1 haad avl_tree_t *local_avl; 2399 1.1 haad nvpair_t *fselem, *nextfselem; 2400 1.3 chs char *fromsnap; 2401 1.3 chs char newname[ZFS_MAX_DATASET_NAME_LEN]; 2402 1.3 chs char guidname[32]; 2403 1.1 haad int error; 2404 1.2 dsl boolean_t needagain, progress, recursive; 2405 1.2 dsl char *s1, *s2; 2406 1.1 haad 2407 1.1 haad VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap)); 2408 1.1 haad 2409 1.2 dsl recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") == 2410 1.2 dsl ENOENT); 2411 1.2 dsl 2412 1.3 chs if (flags->dryrun) 2413 1.1 haad return (0); 2414 1.1 haad 2415 1.1 haad again: 2416 1.1 haad needagain = progress = B_FALSE; 2417 1.1 haad 2418 1.3 chs VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0)); 2419 1.3 chs 2420 1.1 haad if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL, 2421 1.3 chs recursive, B_FALSE, &local_nv, &local_avl)) != 0) 2422 1.1 haad return (error); 2423 1.1 haad 2424 1.1 haad /* 2425 1.1 haad * Process deletes and renames 2426 1.1 haad */ 2427 1.1 haad for (fselem = nvlist_next_nvpair(local_nv, NULL); 2428 1.1 haad fselem; fselem = nextfselem) { 2429 1.1 haad nvlist_t *nvfs, *snaps; 2430 1.1 haad nvlist_t *stream_nvfs = NULL; 2431 1.1 haad nvpair_t *snapelem, *nextsnapelem; 2432 1.1 haad uint64_t fromguid = 0; 2433 1.1 haad uint64_t originguid = 0; 2434 1.1 haad uint64_t stream_originguid = 0; 2435 1.1 haad uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid; 2436 1.1 haad char *fsname, *stream_fsname; 2437 1.1 haad 2438 1.1 haad nextfselem = nvlist_next_nvpair(local_nv, fselem); 2439 1.1 haad 2440 1.1 haad VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs)); 2441 1.1 haad VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps)); 2442 1.1 haad VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname)); 2443 1.1 haad VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap", 2444 1.1 haad &parent_fromsnap_guid)); 2445 1.1 haad (void) nvlist_lookup_uint64(nvfs, "origin", &originguid); 2446 1.1 haad 2447 1.1 haad /* 2448 1.1 haad * First find the stream's fs, so we can check for 2449 1.1 haad * a different origin (due to "zfs promote") 2450 1.1 haad */ 2451 1.1 haad for (snapelem = nvlist_next_nvpair(snaps, NULL); 2452 1.1 haad snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) { 2453 1.1 haad uint64_t thisguid; 2454 1.1 haad 2455 1.1 haad VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid)); 2456 1.1 haad stream_nvfs = fsavl_find(stream_avl, thisguid, NULL); 2457 1.1 haad 2458 1.1 haad if (stream_nvfs != NULL) 2459 1.1 haad break; 2460 1.1 haad } 2461 1.1 haad 2462 1.1 haad /* check for promote */ 2463 1.1 haad (void) nvlist_lookup_uint64(stream_nvfs, "origin", 2464 1.1 haad &stream_originguid); 2465 1.1 haad if (stream_nvfs && originguid != stream_originguid) { 2466 1.1 haad switch (created_before(hdl, local_avl, 2467 1.1 haad stream_originguid, originguid)) { 2468 1.1 haad case 1: { 2469 1.1 haad /* promote it! */ 2470 1.1 haad zfs_cmd_t zc = { 0 }; 2471 1.1 haad nvlist_t *origin_nvfs; 2472 1.1 haad char *origin_fsname; 2473 1.1 haad 2474 1.3 chs if (flags->verbose) 2475 1.1 haad (void) printf("promoting %s\n", fsname); 2476 1.1 haad 2477 1.1 haad origin_nvfs = fsavl_find(local_avl, originguid, 2478 1.1 haad NULL); 2479 1.1 haad VERIFY(0 == nvlist_lookup_string(origin_nvfs, 2480 1.1 haad "name", &origin_fsname)); 2481 1.1 haad (void) strlcpy(zc.zc_value, origin_fsname, 2482 1.1 haad sizeof (zc.zc_value)); 2483 1.1 haad (void) strlcpy(zc.zc_name, fsname, 2484 1.1 haad sizeof (zc.zc_name)); 2485 1.1 haad error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc); 2486 1.1 haad if (error == 0) 2487 1.1 haad progress = B_TRUE; 2488 1.1 haad break; 2489 1.1 haad } 2490 1.1 haad default: 2491 1.1 haad break; 2492 1.1 haad case -1: 2493 1.1 haad fsavl_destroy(local_avl); 2494 1.1 haad nvlist_free(local_nv); 2495 1.1 haad return (-1); 2496 1.1 haad } 2497 1.1 haad /* 2498 1.1 haad * We had/have the wrong origin, therefore our 2499 1.1 haad * list of snapshots is wrong. Need to handle 2500 1.1 haad * them on the next pass. 2501 1.1 haad */ 2502 1.1 haad needagain = B_TRUE; 2503 1.1 haad continue; 2504 1.1 haad } 2505 1.1 haad 2506 1.1 haad for (snapelem = nvlist_next_nvpair(snaps, NULL); 2507 1.1 haad snapelem; snapelem = nextsnapelem) { 2508 1.1 haad uint64_t thisguid; 2509 1.1 haad char *stream_snapname; 2510 1.1 haad nvlist_t *found, *props; 2511 1.1 haad 2512 1.1 haad nextsnapelem = nvlist_next_nvpair(snaps, snapelem); 2513 1.1 haad 2514 1.1 haad VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid)); 2515 1.1 haad found = fsavl_find(stream_avl, thisguid, 2516 1.1 haad &stream_snapname); 2517 1.1 haad 2518 1.1 haad /* check for delete */ 2519 1.1 haad if (found == NULL) { 2520 1.3 chs char name[ZFS_MAX_DATASET_NAME_LEN]; 2521 1.1 haad 2522 1.3 chs if (!flags->force) 2523 1.1 haad continue; 2524 1.1 haad 2525 1.1 haad (void) snprintf(name, sizeof (name), "%s@%s", 2526 1.1 haad fsname, nvpair_name(snapelem)); 2527 1.1 haad 2528 1.1 haad error = recv_destroy(hdl, name, 2529 1.1 haad strlen(fsname)+1, newname, flags); 2530 1.1 haad if (error) 2531 1.1 haad needagain = B_TRUE; 2532 1.1 haad else 2533 1.1 haad progress = B_TRUE; 2534 1.3 chs sprintf(guidname, "%lu", thisguid); 2535 1.3 chs nvlist_add_boolean(deleted, guidname); 2536 1.1 haad continue; 2537 1.1 haad } 2538 1.1 haad 2539 1.1 haad stream_nvfs = found; 2540 1.1 haad 2541 1.1 haad if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops", 2542 1.1 haad &props) && 0 == nvlist_lookup_nvlist(props, 2543 1.1 haad stream_snapname, &props)) { 2544 1.1 haad zfs_cmd_t zc = { 0 }; 2545 1.1 haad 2546 1.2 dsl zc.zc_cookie = B_TRUE; /* received */ 2547 1.1 haad (void) snprintf(zc.zc_name, sizeof (zc.zc_name), 2548 1.1 haad "%s@%s", fsname, nvpair_name(snapelem)); 2549 1.1 haad if (zcmd_write_src_nvlist(hdl, &zc, 2550 1.1 haad props) == 0) { 2551 1.1 haad (void) zfs_ioctl(hdl, 2552 1.1 haad ZFS_IOC_SET_PROP, &zc); 2553 1.1 haad zcmd_free_nvlists(&zc); 2554 1.1 haad } 2555 1.1 haad } 2556 1.1 haad 2557 1.1 haad /* check for different snapname */ 2558 1.1 haad if (strcmp(nvpair_name(snapelem), 2559 1.1 haad stream_snapname) != 0) { 2560 1.3 chs char name[ZFS_MAX_DATASET_NAME_LEN]; 2561 1.3 chs char tryname[ZFS_MAX_DATASET_NAME_LEN]; 2562 1.1 haad 2563 1.1 haad (void) snprintf(name, sizeof (name), "%s@%s", 2564 1.1 haad fsname, nvpair_name(snapelem)); 2565 1.1 haad (void) snprintf(tryname, sizeof (name), "%s@%s", 2566 1.1 haad fsname, stream_snapname); 2567 1.1 haad 2568 1.1 haad error = recv_rename(hdl, name, tryname, 2569 1.1 haad strlen(fsname)+1, newname, flags); 2570 1.1 haad if (error) 2571 1.1 haad needagain = B_TRUE; 2572 1.1 haad else 2573 1.1 haad progress = B_TRUE; 2574 1.1 haad } 2575 1.1 haad 2576 1.1 haad if (strcmp(stream_snapname, fromsnap) == 0) 2577 1.1 haad fromguid = thisguid; 2578 1.1 haad } 2579 1.1 haad 2580 1.1 haad /* check for delete */ 2581 1.1 haad if (stream_nvfs == NULL) { 2582 1.3 chs if (!flags->force) 2583 1.1 haad continue; 2584 1.1 haad 2585 1.1 haad error = recv_destroy(hdl, fsname, strlen(tofs)+1, 2586 1.1 haad newname, flags); 2587 1.1 haad if (error) 2588 1.1 haad needagain = B_TRUE; 2589 1.1 haad else 2590 1.1 haad progress = B_TRUE; 2591 1.3 chs sprintf(guidname, "%lu", parent_fromsnap_guid); 2592 1.3 chs nvlist_add_boolean(deleted, guidname); 2593 1.1 haad continue; 2594 1.1 haad } 2595 1.1 haad 2596 1.3 chs if (fromguid == 0) { 2597 1.3 chs if (flags->verbose) { 2598 1.3 chs (void) printf("local fs %s does not have " 2599 1.3 chs "fromsnap (%s in stream); must have " 2600 1.3 chs "been deleted locally; ignoring\n", 2601 1.3 chs fsname, fromsnap); 2602 1.3 chs } 2603 1.1 haad continue; 2604 1.1 haad } 2605 1.1 haad 2606 1.1 haad VERIFY(0 == nvlist_lookup_string(stream_nvfs, 2607 1.1 haad "name", &stream_fsname)); 2608 1.1 haad VERIFY(0 == nvlist_lookup_uint64(stream_nvfs, 2609 1.1 haad "parentfromsnap", &stream_parent_fromsnap_guid)); 2610 1.1 haad 2611 1.2 dsl s1 = strrchr(fsname, '/'); 2612 1.2 dsl s2 = strrchr(stream_fsname, '/'); 2613 1.2 dsl 2614 1.3 chs /* 2615 1.3 chs * Check if we're going to rename based on parent guid change 2616 1.3 chs * and the current parent guid was also deleted. If it was then 2617 1.3 chs * rename will fail and is likely unneeded, so avoid this and 2618 1.3 chs * force an early retry to determine the new 2619 1.3 chs * parent_fromsnap_guid. 2620 1.3 chs */ 2621 1.3 chs if (stream_parent_fromsnap_guid != 0 && 2622 1.3 chs parent_fromsnap_guid != 0 && 2623 1.3 chs stream_parent_fromsnap_guid != parent_fromsnap_guid) { 2624 1.3 chs sprintf(guidname, "%lu", parent_fromsnap_guid); 2625 1.3 chs if (nvlist_exists(deleted, guidname)) { 2626 1.3 chs progress = B_TRUE; 2627 1.3 chs needagain = B_TRUE; 2628 1.3 chs goto doagain; 2629 1.3 chs } 2630 1.3 chs } 2631 1.3 chs 2632 1.3 chs /* 2633 1.3 chs * Check for rename. If the exact receive path is specified, it 2634 1.3 chs * does not count as a rename, but we still need to check the 2635 1.3 chs * datasets beneath it. 2636 1.3 chs */ 2637 1.1 haad if ((stream_parent_fromsnap_guid != 0 && 2638 1.3 chs parent_fromsnap_guid != 0 && 2639 1.1 haad stream_parent_fromsnap_guid != parent_fromsnap_guid) || 2640 1.3 chs ((flags->isprefix || strcmp(tofs, fsname) != 0) && 2641 1.3 chs (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) { 2642 1.1 haad nvlist_t *parent; 2643 1.3 chs char tryname[ZFS_MAX_DATASET_NAME_LEN]; 2644 1.1 haad 2645 1.1 haad parent = fsavl_find(local_avl, 2646 1.1 haad stream_parent_fromsnap_guid, NULL); 2647 1.1 haad /* 2648 1.1 haad * NB: parent might not be found if we used the 2649 1.1 haad * tosnap for stream_parent_fromsnap_guid, 2650 1.1 haad * because the parent is a newly-created fs; 2651 1.1 haad * we'll be able to rename it after we recv the 2652 1.1 haad * new fs. 2653 1.1 haad */ 2654 1.1 haad if (parent != NULL) { 2655 1.1 haad char *pname; 2656 1.1 haad 2657 1.1 haad VERIFY(0 == nvlist_lookup_string(parent, "name", 2658 1.1 haad &pname)); 2659 1.1 haad (void) snprintf(tryname, sizeof (tryname), 2660 1.1 haad "%s%s", pname, strrchr(stream_fsname, '/')); 2661 1.1 haad } else { 2662 1.1 haad tryname[0] = '\0'; 2663 1.3 chs if (flags->verbose) { 2664 1.1 haad (void) printf("local fs %s new parent " 2665 1.1 haad "not found\n", fsname); 2666 1.1 haad } 2667 1.1 haad } 2668 1.1 haad 2669 1.3 chs newname[0] = '\0'; 2670 1.3 chs 2671 1.1 haad error = recv_rename(hdl, fsname, tryname, 2672 1.1 haad strlen(tofs)+1, newname, flags); 2673 1.3 chs 2674 1.3 chs if (renamed != NULL && newname[0] != '\0') { 2675 1.3 chs VERIFY(0 == nvlist_add_boolean(renamed, 2676 1.3 chs newname)); 2677 1.3 chs } 2678 1.3 chs 2679 1.1 haad if (error) 2680 1.1 haad needagain = B_TRUE; 2681 1.1 haad else 2682 1.1 haad progress = B_TRUE; 2683 1.1 haad } 2684 1.1 haad } 2685 1.1 haad 2686 1.3 chs doagain: 2687 1.1 haad fsavl_destroy(local_avl); 2688 1.1 haad nvlist_free(local_nv); 2689 1.3 chs nvlist_free(deleted); 2690 1.1 haad 2691 1.1 haad if (needagain && progress) { 2692 1.1 haad /* do another pass to fix up temporary names */ 2693 1.3 chs if (flags->verbose) 2694 1.1 haad (void) printf("another pass:\n"); 2695 1.1 haad goto again; 2696 1.1 haad } 2697 1.1 haad 2698 1.1 haad return (needagain); 2699 1.1 haad } 2700 1.1 haad 2701 1.1 haad static int 2702 1.1 haad zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname, 2703 1.3 chs recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc, 2704 1.3 chs char **top_zfs, int cleanup_fd, uint64_t *action_handlep) 2705 1.1 haad { 2706 1.1 haad nvlist_t *stream_nv = NULL; 2707 1.1 haad avl_tree_t *stream_avl = NULL; 2708 1.1 haad char *fromsnap = NULL; 2709 1.3 chs char *sendsnap = NULL; 2710 1.3 chs char *cp; 2711 1.3 chs char tofs[ZFS_MAX_DATASET_NAME_LEN]; 2712 1.3 chs char sendfs[ZFS_MAX_DATASET_NAME_LEN]; 2713 1.1 haad char errbuf[1024]; 2714 1.1 haad dmu_replay_record_t drre; 2715 1.1 haad int error; 2716 1.1 haad boolean_t anyerr = B_FALSE; 2717 1.1 haad boolean_t softerr = B_FALSE; 2718 1.3 chs boolean_t recursive; 2719 1.1 haad 2720 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2721 1.1 haad "cannot receive")); 2722 1.1 haad 2723 1.1 haad assert(drr->drr_type == DRR_BEGIN); 2724 1.1 haad assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC); 2725 1.2 dsl assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) == 2726 1.2 dsl DMU_COMPOUNDSTREAM); 2727 1.1 haad 2728 1.1 haad /* 2729 1.1 haad * Read in the nvlist from the stream. 2730 1.1 haad */ 2731 1.1 haad if (drr->drr_payloadlen != 0) { 2732 1.1 haad error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen, 2733 1.3 chs &stream_nv, flags->byteswap, zc); 2734 1.1 haad if (error) { 2735 1.1 haad error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 2736 1.1 haad goto out; 2737 1.1 haad } 2738 1.1 haad } 2739 1.1 haad 2740 1.3 chs recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") == 2741 1.3 chs ENOENT); 2742 1.3 chs 2743 1.3 chs if (recursive && strchr(destname, '@')) { 2744 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2745 1.3 chs "cannot specify snapshot name for multi-snapshot stream")); 2746 1.3 chs error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 2747 1.3 chs goto out; 2748 1.3 chs } 2749 1.3 chs 2750 1.1 haad /* 2751 1.1 haad * Read in the end record and verify checksum. 2752 1.1 haad */ 2753 1.1 haad if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre), 2754 1.3 chs flags->byteswap, NULL))) 2755 1.1 haad goto out; 2756 1.3 chs if (flags->byteswap) { 2757 1.1 haad drre.drr_type = BSWAP_32(drre.drr_type); 2758 1.1 haad drre.drr_u.drr_end.drr_checksum.zc_word[0] = 2759 1.1 haad BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]); 2760 1.1 haad drre.drr_u.drr_end.drr_checksum.zc_word[1] = 2761 1.1 haad BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]); 2762 1.1 haad drre.drr_u.drr_end.drr_checksum.zc_word[2] = 2763 1.1 haad BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]); 2764 1.1 haad drre.drr_u.drr_end.drr_checksum.zc_word[3] = 2765 1.1 haad BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]); 2766 1.1 haad } 2767 1.1 haad if (drre.drr_type != DRR_END) { 2768 1.1 haad error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 2769 1.1 haad goto out; 2770 1.1 haad } 2771 1.1 haad if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) { 2772 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2773 1.1 haad "incorrect header checksum")); 2774 1.1 haad error = zfs_error(hdl, EZFS_BADSTREAM, errbuf); 2775 1.1 haad goto out; 2776 1.1 haad } 2777 1.1 haad 2778 1.1 haad (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap); 2779 1.1 haad 2780 1.1 haad if (drr->drr_payloadlen != 0) { 2781 1.1 haad nvlist_t *stream_fss; 2782 1.1 haad 2783 1.1 haad VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss", 2784 1.1 haad &stream_fss)); 2785 1.1 haad if ((stream_avl = fsavl_create(stream_fss)) == NULL) { 2786 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2787 1.1 haad "couldn't allocate avl tree")); 2788 1.1 haad error = zfs_error(hdl, EZFS_NOMEM, errbuf); 2789 1.1 haad goto out; 2790 1.1 haad } 2791 1.1 haad 2792 1.1 haad if (fromsnap != NULL) { 2793 1.3 chs nvlist_t *renamed = NULL; 2794 1.3 chs nvpair_t *pair = NULL; 2795 1.3 chs 2796 1.3 chs (void) strlcpy(tofs, destname, sizeof (tofs)); 2797 1.3 chs if (flags->isprefix) { 2798 1.3 chs struct drr_begin *drrb = &drr->drr_u.drr_begin; 2799 1.3 chs int i; 2800 1.3 chs 2801 1.3 chs if (flags->istail) { 2802 1.3 chs cp = strrchr(drrb->drr_toname, '/'); 2803 1.3 chs if (cp == NULL) { 2804 1.3 chs (void) strlcat(tofs, "/", 2805 1.3 chs sizeof (tofs)); 2806 1.3 chs i = 0; 2807 1.3 chs } else { 2808 1.3 chs i = (cp - drrb->drr_toname); 2809 1.3 chs } 2810 1.3 chs } else { 2811 1.3 chs i = strcspn(drrb->drr_toname, "/@"); 2812 1.3 chs } 2813 1.1 haad /* zfs_receive_one() will create_parents() */ 2814 1.3 chs (void) strlcat(tofs, &drrb->drr_toname[i], 2815 1.3 chs sizeof (tofs)); 2816 1.1 haad *strchr(tofs, '@') = '\0'; 2817 1.1 haad } 2818 1.3 chs 2819 1.3 chs if (recursive && !flags->dryrun && !flags->nomount) { 2820 1.3 chs VERIFY(0 == nvlist_alloc(&renamed, 2821 1.3 chs NV_UNIQUE_NAME, 0)); 2822 1.3 chs } 2823 1.3 chs 2824 1.3 chs softerr = recv_incremental_replication(hdl, tofs, flags, 2825 1.3 chs stream_nv, stream_avl, renamed); 2826 1.3 chs 2827 1.3 chs /* Unmount renamed filesystems before receiving. */ 2828 1.3 chs while ((pair = nvlist_next_nvpair(renamed, 2829 1.3 chs pair)) != NULL) { 2830 1.3 chs zfs_handle_t *zhp; 2831 1.3 chs prop_changelist_t *clp = NULL; 2832 1.3 chs 2833 1.3 chs zhp = zfs_open(hdl, nvpair_name(pair), 2834 1.3 chs ZFS_TYPE_FILESYSTEM); 2835 1.3 chs if (zhp != NULL) { 2836 1.3 chs clp = changelist_gather(zhp, 2837 1.3 chs ZFS_PROP_MOUNTPOINT, 0, 0); 2838 1.3 chs zfs_close(zhp); 2839 1.3 chs if (clp != NULL) { 2840 1.3 chs softerr |= 2841 1.3 chs changelist_prefix(clp); 2842 1.3 chs changelist_free(clp); 2843 1.3 chs } 2844 1.3 chs } 2845 1.3 chs } 2846 1.3 chs 2847 1.3 chs nvlist_free(renamed); 2848 1.1 haad } 2849 1.1 haad } 2850 1.1 haad 2851 1.3 chs /* 2852 1.3 chs * Get the fs specified by the first path in the stream (the top level 2853 1.3 chs * specified by 'zfs send') and pass it to each invocation of 2854 1.3 chs * zfs_receive_one(). 2855 1.3 chs */ 2856 1.3 chs (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname, 2857 1.3 chs sizeof (sendfs)); 2858 1.3 chs if ((cp = strchr(sendfs, '@')) != NULL) { 2859 1.3 chs *cp = '\0'; 2860 1.3 chs /* 2861 1.3 chs * Find the "sendsnap", the final snapshot in a replication 2862 1.3 chs * stream. zfs_receive_one() handles certain errors 2863 1.3 chs * differently, depending on if the contained stream is the 2864 1.3 chs * last one or not. 2865 1.3 chs */ 2866 1.3 chs sendsnap = (cp + 1); 2867 1.3 chs } 2868 1.1 haad 2869 1.1 haad /* Finally, receive each contained stream */ 2870 1.1 haad do { 2871 1.1 haad /* 2872 1.1 haad * we should figure out if it has a recoverable 2873 1.1 haad * error, in which case do a recv_skip() and drive on. 2874 1.1 haad * Note, if we fail due to already having this guid, 2875 1.1 haad * zfs_receive_one() will take care of it (ie, 2876 1.1 haad * recv_skip() and return 0). 2877 1.1 haad */ 2878 1.3 chs error = zfs_receive_impl(hdl, destname, NULL, flags, fd, 2879 1.3 chs sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd, 2880 1.3 chs action_handlep, sendsnap); 2881 1.1 haad if (error == ENODATA) { 2882 1.1 haad error = 0; 2883 1.1 haad break; 2884 1.1 haad } 2885 1.1 haad anyerr |= error; 2886 1.1 haad } while (error == 0); 2887 1.1 haad 2888 1.1 haad if (drr->drr_payloadlen != 0 && fromsnap != NULL) { 2889 1.1 haad /* 2890 1.1 haad * Now that we have the fs's they sent us, try the 2891 1.1 haad * renames again. 2892 1.1 haad */ 2893 1.1 haad softerr = recv_incremental_replication(hdl, tofs, flags, 2894 1.3 chs stream_nv, stream_avl, NULL); 2895 1.1 haad } 2896 1.1 haad 2897 1.1 haad out: 2898 1.1 haad fsavl_destroy(stream_avl); 2899 1.3 chs nvlist_free(stream_nv); 2900 1.1 haad if (softerr) 2901 1.1 haad error = -2; 2902 1.1 haad if (anyerr) 2903 1.1 haad error = -1; 2904 1.1 haad return (error); 2905 1.1 haad } 2906 1.1 haad 2907 1.2 dsl static void 2908 1.2 dsl trunc_prop_errs(int truncated) 2909 1.2 dsl { 2910 1.2 dsl ASSERT(truncated != 0); 2911 1.2 dsl 2912 1.2 dsl if (truncated == 1) 2913 1.2 dsl (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 2914 1.2 dsl "1 more property could not be set\n")); 2915 1.2 dsl else 2916 1.2 dsl (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 2917 1.2 dsl "%d more properties could not be set\n"), truncated); 2918 1.2 dsl } 2919 1.2 dsl 2920 1.1 haad static int 2921 1.1 haad recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap) 2922 1.1 haad { 2923 1.1 haad dmu_replay_record_t *drr; 2924 1.3 chs void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE); 2925 1.2 dsl char errbuf[1024]; 2926 1.2 dsl 2927 1.2 dsl (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2928 1.2 dsl "cannot receive:")); 2929 1.1 haad 2930 1.1 haad /* XXX would be great to use lseek if possible... */ 2931 1.1 haad drr = buf; 2932 1.1 haad 2933 1.1 haad while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t), 2934 1.1 haad byteswap, NULL) == 0) { 2935 1.1 haad if (byteswap) 2936 1.1 haad drr->drr_type = BSWAP_32(drr->drr_type); 2937 1.1 haad 2938 1.1 haad switch (drr->drr_type) { 2939 1.1 haad case DRR_BEGIN: 2940 1.2 dsl if (drr->drr_payloadlen != 0) { 2941 1.3 chs (void) recv_read(hdl, fd, buf, 2942 1.3 chs drr->drr_payloadlen, B_FALSE, NULL); 2943 1.2 dsl } 2944 1.1 haad break; 2945 1.1 haad 2946 1.1 haad case DRR_END: 2947 1.1 haad free(buf); 2948 1.1 haad return (0); 2949 1.1 haad 2950 1.1 haad case DRR_OBJECT: 2951 1.1 haad if (byteswap) { 2952 1.1 haad drr->drr_u.drr_object.drr_bonuslen = 2953 1.1 haad BSWAP_32(drr->drr_u.drr_object. 2954 1.1 haad drr_bonuslen); 2955 1.1 haad } 2956 1.1 haad (void) recv_read(hdl, fd, buf, 2957 1.1 haad P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8), 2958 1.1 haad B_FALSE, NULL); 2959 1.1 haad break; 2960 1.1 haad 2961 1.1 haad case DRR_WRITE: 2962 1.1 haad if (byteswap) { 2963 1.1 haad drr->drr_u.drr_write.drr_length = 2964 1.1 haad BSWAP_64(drr->drr_u.drr_write.drr_length); 2965 1.1 haad } 2966 1.1 haad (void) recv_read(hdl, fd, buf, 2967 1.1 haad drr->drr_u.drr_write.drr_length, B_FALSE, NULL); 2968 1.1 haad break; 2969 1.3 chs case DRR_SPILL: 2970 1.3 chs if (byteswap) { 2971 1.3 chs drr->drr_u.drr_spill.drr_length = 2972 1.3 chs BSWAP_64(drr->drr_u.drr_spill.drr_length); 2973 1.3 chs } 2974 1.3 chs (void) recv_read(hdl, fd, buf, 2975 1.3 chs drr->drr_u.drr_spill.drr_length, B_FALSE, NULL); 2976 1.3 chs break; 2977 1.3 chs case DRR_WRITE_EMBEDDED: 2978 1.3 chs if (byteswap) { 2979 1.3 chs drr->drr_u.drr_write_embedded.drr_psize = 2980 1.3 chs BSWAP_32(drr->drr_u.drr_write_embedded. 2981 1.3 chs drr_psize); 2982 1.3 chs } 2983 1.3 chs (void) recv_read(hdl, fd, buf, 2984 1.3 chs P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize, 2985 1.3 chs 8), B_FALSE, NULL); 2986 1.3 chs break; 2987 1.2 dsl case DRR_WRITE_BYREF: 2988 1.1 haad case DRR_FREEOBJECTS: 2989 1.1 haad case DRR_FREE: 2990 1.1 haad break; 2991 1.1 haad 2992 1.1 haad default: 2993 1.2 dsl zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2994 1.2 dsl "invalid record type")); 2995 1.2 dsl return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 2996 1.1 haad } 2997 1.1 haad } 2998 1.1 haad 2999 1.1 haad free(buf); 3000 1.1 haad return (-1); 3001 1.1 haad } 3002 1.1 haad 3003 1.3 chs static void 3004 1.3 chs recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap, 3005 1.3 chs boolean_t resumable) 3006 1.3 chs { 3007 1.3 chs char target_fs[ZFS_MAX_DATASET_NAME_LEN]; 3008 1.3 chs 3009 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3010 1.3 chs "checksum mismatch or incomplete stream")); 3011 1.3 chs 3012 1.3 chs if (!resumable) 3013 1.3 chs return; 3014 1.3 chs (void) strlcpy(target_fs, target_snap, sizeof (target_fs)); 3015 1.3 chs *strchr(target_fs, '@') = '\0'; 3016 1.3 chs zfs_handle_t *zhp = zfs_open(hdl, target_fs, 3017 1.3 chs ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); 3018 1.3 chs if (zhp == NULL) 3019 1.3 chs return; 3020 1.3 chs 3021 1.3 chs char token_buf[ZFS_MAXPROPLEN]; 3022 1.3 chs int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, 3023 1.3 chs token_buf, sizeof (token_buf), 3024 1.3 chs NULL, NULL, 0, B_TRUE); 3025 1.3 chs if (error == 0) { 3026 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3027 1.3 chs "checksum mismatch or incomplete stream.\n" 3028 1.3 chs "Partially received snapshot is saved.\n" 3029 1.3 chs "A resuming stream can be generated on the sending " 3030 1.3 chs "system by running:\n" 3031 1.3 chs " zfs send -t %s"), 3032 1.3 chs token_buf); 3033 1.3 chs } 3034 1.3 chs zfs_close(zhp); 3035 1.3 chs } 3036 1.3 chs 3037 1.1 haad /* 3038 1.1 haad * Restores a backup of tosnap from the file descriptor specified by infd. 3039 1.1 haad */ 3040 1.1 haad static int 3041 1.1 haad zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, 3042 1.3 chs const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr, 3043 1.3 chs dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv, 3044 1.3 chs avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd, 3045 1.3 chs uint64_t *action_handlep, const char *finalsnap) 3046 1.1 haad { 3047 1.1 haad zfs_cmd_t zc = { 0 }; 3048 1.1 haad time_t begin_time; 3049 1.3 chs int ioctl_err, ioctl_errno, err; 3050 1.1 haad char *cp; 3051 1.1 haad struct drr_begin *drrb = &drr->drr_u.drr_begin; 3052 1.1 haad char errbuf[1024]; 3053 1.2 dsl char prop_errbuf[1024]; 3054 1.3 chs const char *chopprefix; 3055 1.1 haad boolean_t newfs = B_FALSE; 3056 1.1 haad boolean_t stream_wantsnewfs; 3057 1.1 haad uint64_t parent_snapguid = 0; 3058 1.1 haad prop_changelist_t *clp = NULL; 3059 1.1 haad nvlist_t *snapprops_nvlist = NULL; 3060 1.2 dsl zprop_errflags_t prop_errflags; 3061 1.3 chs boolean_t recursive; 3062 1.3 chs char *snapname = NULL; 3063 1.1 haad 3064 1.1 haad begin_time = time(NULL); 3065 1.1 haad 3066 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3067 1.1 haad "cannot receive")); 3068 1.1 haad 3069 1.3 chs recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") == 3070 1.3 chs ENOENT); 3071 1.3 chs 3072 1.1 haad if (stream_avl != NULL) { 3073 1.1 haad nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid, 3074 1.1 haad &snapname); 3075 1.1 haad nvlist_t *props; 3076 1.1 haad int ret; 3077 1.1 haad 3078 1.1 haad (void) nvlist_lookup_uint64(fs, "parentfromsnap", 3079 1.1 haad &parent_snapguid); 3080 1.1 haad err = nvlist_lookup_nvlist(fs, "props", &props); 3081 1.1 haad if (err) 3082 1.1 haad VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0)); 3083 1.1 haad 3084 1.3 chs if (flags->canmountoff) { 3085 1.1 haad VERIFY(0 == nvlist_add_uint64(props, 3086 1.1 haad zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0)); 3087 1.1 haad } 3088 1.1 haad ret = zcmd_write_src_nvlist(hdl, &zc, props); 3089 1.1 haad if (err) 3090 1.1 haad nvlist_free(props); 3091 1.1 haad 3092 1.1 haad if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) { 3093 1.1 haad VERIFY(0 == nvlist_lookup_nvlist(props, 3094 1.1 haad snapname, &snapprops_nvlist)); 3095 1.1 haad } 3096 1.1 haad 3097 1.1 haad if (ret != 0) 3098 1.1 haad return (-1); 3099 1.1 haad } 3100 1.1 haad 3101 1.3 chs cp = NULL; 3102 1.3 chs 3103 1.1 haad /* 3104 1.1 haad * Determine how much of the snapshot name stored in the stream 3105 1.1 haad * we are going to tack on to the name they specified on the 3106 1.1 haad * command line, and how much we are going to chop off. 3107 1.1 haad * 3108 1.1 haad * If they specified a snapshot, chop the entire name stored in 3109 1.1 haad * the stream. 3110 1.1 haad */ 3111 1.3 chs if (flags->istail) { 3112 1.3 chs /* 3113 1.3 chs * A filesystem was specified with -e. We want to tack on only 3114 1.3 chs * the tail of the sent snapshot path. 3115 1.3 chs */ 3116 1.3 chs if (strchr(tosnap, '@')) { 3117 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 3118 1.3 chs "argument - snapshot not allowed with -e")); 3119 1.3 chs return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3120 1.3 chs } 3121 1.3 chs 3122 1.3 chs chopprefix = strrchr(sendfs, '/'); 3123 1.3 chs 3124 1.3 chs if (chopprefix == NULL) { 3125 1.3 chs /* 3126 1.3 chs * The tail is the poolname, so we need to 3127 1.3 chs * prepend a path separator. 3128 1.3 chs */ 3129 1.3 chs int len = strlen(drrb->drr_toname); 3130 1.3 chs cp = malloc(len + 2); 3131 1.3 chs cp[0] = '/'; 3132 1.3 chs (void) strcpy(&cp[1], drrb->drr_toname); 3133 1.3 chs chopprefix = cp; 3134 1.3 chs } else { 3135 1.3 chs chopprefix = drrb->drr_toname + (chopprefix - sendfs); 3136 1.3 chs } 3137 1.3 chs } else if (flags->isprefix) { 3138 1.1 haad /* 3139 1.3 chs * A filesystem was specified with -d. We want to tack on 3140 1.2 dsl * everything but the first element of the sent snapshot path 3141 1.3 chs * (all but the pool name). 3142 1.1 haad */ 3143 1.1 haad if (strchr(tosnap, '@')) { 3144 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 3145 1.3 chs "argument - snapshot not allowed with -d")); 3146 1.1 haad return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3147 1.1 haad } 3148 1.3 chs 3149 1.3 chs chopprefix = strchr(drrb->drr_toname, '/'); 3150 1.3 chs if (chopprefix == NULL) 3151 1.3 chs chopprefix = strchr(drrb->drr_toname, '@'); 3152 1.1 haad } else if (strchr(tosnap, '@') == NULL) { 3153 1.1 haad /* 3154 1.3 chs * If a filesystem was specified without -d or -e, we want to 3155 1.3 chs * tack on everything after the fs specified by 'zfs send'. 3156 1.1 haad */ 3157 1.3 chs chopprefix = drrb->drr_toname + strlen(sendfs); 3158 1.3 chs } else { 3159 1.3 chs /* A snapshot was specified as an exact path (no -d or -e). */ 3160 1.3 chs if (recursive) { 3161 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3162 1.3 chs "cannot specify snapshot name for multi-snapshot " 3163 1.3 chs "stream")); 3164 1.3 chs return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 3165 1.3 chs } 3166 1.3 chs chopprefix = drrb->drr_toname + strlen(drrb->drr_toname); 3167 1.1 haad } 3168 1.3 chs 3169 1.3 chs ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname); 3170 1.3 chs ASSERT(chopprefix > drrb->drr_toname); 3171 1.3 chs ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname)); 3172 1.3 chs ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' || 3173 1.3 chs chopprefix[0] == '\0'); 3174 1.1 haad 3175 1.1 haad /* 3176 1.1 haad * Determine name of destination snapshot, store in zc_value. 3177 1.1 haad */ 3178 1.1 haad (void) strcpy(zc.zc_value, tosnap); 3179 1.3 chs (void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value)); 3180 1.3 chs #ifdef __FreeBSD__ 3181 1.3 chs if (zfs_ioctl_version == ZFS_IOCVER_UNDEF) 3182 1.3 chs zfs_ioctl_version = get_zfs_ioctl_version(); 3183 1.3 chs /* 3184 1.3 chs * For forward compatibility hide tosnap in zc_value 3185 1.3 chs */ 3186 1.3 chs if (zfs_ioctl_version < ZFS_IOCVER_LZC) 3187 1.3 chs (void) strcpy(zc.zc_value + strlen(zc.zc_value) + 1, tosnap); 3188 1.3 chs #endif 3189 1.3 chs free(cp); 3190 1.1 haad if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) { 3191 1.1 haad zcmd_free_nvlists(&zc); 3192 1.1 haad return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3193 1.1 haad } 3194 1.1 haad 3195 1.1 haad /* 3196 1.1 haad * Determine the name of the origin snapshot, store in zc_string. 3197 1.1 haad */ 3198 1.1 haad if (drrb->drr_flags & DRR_FLAG_CLONE) { 3199 1.3 chs if (guid_to_name(hdl, zc.zc_value, 3200 1.3 chs drrb->drr_fromguid, B_FALSE, zc.zc_string) != 0) { 3201 1.1 haad zcmd_free_nvlists(&zc); 3202 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3203 1.1 haad "local origin for clone %s does not exist"), 3204 1.1 haad zc.zc_value); 3205 1.1 haad return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3206 1.1 haad } 3207 1.3 chs if (flags->verbose) 3208 1.1 haad (void) printf("found clone origin %s\n", zc.zc_string); 3209 1.3 chs } else if (originsnap) { 3210 1.3 chs (void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string)); 3211 1.3 chs if (flags->verbose) 3212 1.3 chs (void) printf("using provided clone origin %s\n", 3213 1.3 chs zc.zc_string); 3214 1.1 haad } 3215 1.1 haad 3216 1.3 chs boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) & 3217 1.3 chs DMU_BACKUP_FEATURE_RESUMING; 3218 1.2 dsl stream_wantsnewfs = (drrb->drr_fromguid == 0 || 3219 1.3 chs (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming; 3220 1.1 haad 3221 1.1 haad if (stream_wantsnewfs) { 3222 1.1 haad /* 3223 1.1 haad * if the parent fs does not exist, look for it based on 3224 1.1 haad * the parent snap GUID 3225 1.1 haad */ 3226 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3227 1.1 haad "cannot receive new filesystem stream")); 3228 1.1 haad 3229 1.1 haad (void) strcpy(zc.zc_name, zc.zc_value); 3230 1.1 haad cp = strrchr(zc.zc_name, '/'); 3231 1.1 haad if (cp) 3232 1.1 haad *cp = '\0'; 3233 1.1 haad if (cp && 3234 1.1 haad !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 3235 1.3 chs char suffix[ZFS_MAX_DATASET_NAME_LEN]; 3236 1.1 haad (void) strcpy(suffix, strrchr(zc.zc_value, '/')); 3237 1.3 chs if (guid_to_name(hdl, zc.zc_name, parent_snapguid, 3238 1.3 chs B_FALSE, zc.zc_value) == 0) { 3239 1.1 haad *strchr(zc.zc_value, '@') = '\0'; 3240 1.1 haad (void) strcat(zc.zc_value, suffix); 3241 1.1 haad } 3242 1.1 haad } 3243 1.1 haad } else { 3244 1.1 haad /* 3245 1.1 haad * if the fs does not exist, look for it based on the 3246 1.1 haad * fromsnap GUID 3247 1.1 haad */ 3248 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3249 1.1 haad "cannot receive incremental stream")); 3250 1.1 haad 3251 1.1 haad (void) strcpy(zc.zc_name, zc.zc_value); 3252 1.1 haad *strchr(zc.zc_name, '@') = '\0'; 3253 1.1 haad 3254 1.3 chs /* 3255 1.3 chs * If the exact receive path was specified and this is the 3256 1.3 chs * topmost path in the stream, then if the fs does not exist we 3257 1.3 chs * should look no further. 3258 1.3 chs */ 3259 1.3 chs if ((flags->isprefix || (*(chopprefix = drrb->drr_toname + 3260 1.3 chs strlen(sendfs)) != '\0' && *chopprefix != '@')) && 3261 1.3 chs !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 3262 1.3 chs char snap[ZFS_MAX_DATASET_NAME_LEN]; 3263 1.1 haad (void) strcpy(snap, strchr(zc.zc_value, '@')); 3264 1.3 chs if (guid_to_name(hdl, zc.zc_name, drrb->drr_fromguid, 3265 1.3 chs B_FALSE, zc.zc_value) == 0) { 3266 1.1 haad *strchr(zc.zc_value, '@') = '\0'; 3267 1.1 haad (void) strcat(zc.zc_value, snap); 3268 1.1 haad } 3269 1.1 haad } 3270 1.1 haad } 3271 1.1 haad 3272 1.1 haad (void) strcpy(zc.zc_name, zc.zc_value); 3273 1.1 haad *strchr(zc.zc_name, '@') = '\0'; 3274 1.1 haad 3275 1.1 haad if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { 3276 1.1 haad zfs_handle_t *zhp; 3277 1.3 chs 3278 1.1 haad /* 3279 1.3 chs * Destination fs exists. It must be one of these cases: 3280 1.3 chs * - an incremental send stream 3281 1.3 chs * - the stream specifies a new fs (full stream or clone) 3282 1.3 chs * and they want us to blow away the existing fs (and 3283 1.3 chs * have therefore specified -F and removed any snapshots) 3284 1.3 chs * - we are resuming a failed receive. 3285 1.1 haad */ 3286 1.1 haad if (stream_wantsnewfs) { 3287 1.3 chs if (!flags->force) { 3288 1.1 haad zcmd_free_nvlists(&zc); 3289 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3290 1.1 haad "destination '%s' exists\n" 3291 1.1 haad "must specify -F to overwrite it"), 3292 1.1 haad zc.zc_name); 3293 1.1 haad return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 3294 1.1 haad } 3295 1.1 haad if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT, 3296 1.1 haad &zc) == 0) { 3297 1.1 haad zcmd_free_nvlists(&zc); 3298 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3299 1.1 haad "destination has snapshots (eg. %s)\n" 3300 1.1 haad "must destroy them to overwrite it"), 3301 1.1 haad zc.zc_name); 3302 1.1 haad return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 3303 1.1 haad } 3304 1.1 haad } 3305 1.1 haad 3306 1.1 haad if ((zhp = zfs_open(hdl, zc.zc_name, 3307 1.1 haad ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) { 3308 1.1 haad zcmd_free_nvlists(&zc); 3309 1.1 haad return (-1); 3310 1.1 haad } 3311 1.1 haad 3312 1.1 haad if (stream_wantsnewfs && 3313 1.1 haad zhp->zfs_dmustats.dds_origin[0]) { 3314 1.1 haad zcmd_free_nvlists(&zc); 3315 1.1 haad zfs_close(zhp); 3316 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3317 1.1 haad "destination '%s' is a clone\n" 3318 1.1 haad "must destroy it to overwrite it"), 3319 1.1 haad zc.zc_name); 3320 1.1 haad return (zfs_error(hdl, EZFS_EXISTS, errbuf)); 3321 1.1 haad } 3322 1.1 haad 3323 1.3 chs if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM && 3324 1.1 haad stream_wantsnewfs) { 3325 1.1 haad /* We can't do online recv in this case */ 3326 1.1 haad clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0); 3327 1.1 haad if (clp == NULL) { 3328 1.2 dsl zfs_close(zhp); 3329 1.1 haad zcmd_free_nvlists(&zc); 3330 1.1 haad return (-1); 3331 1.1 haad } 3332 1.1 haad if (changelist_prefix(clp) != 0) { 3333 1.1 haad changelist_free(clp); 3334 1.2 dsl zfs_close(zhp); 3335 1.1 haad zcmd_free_nvlists(&zc); 3336 1.1 haad return (-1); 3337 1.1 haad } 3338 1.1 haad } 3339 1.3 chs 3340 1.3 chs /* 3341 1.3 chs * If we are resuming a newfs, set newfs here so that we will 3342 1.3 chs * mount it if the recv succeeds this time. We can tell 3343 1.3 chs * that it was a newfs on the first recv because the fs 3344 1.3 chs * itself will be inconsistent (if the fs existed when we 3345 1.3 chs * did the first recv, we would have received it into 3346 1.3 chs * .../%recv). 3347 1.3 chs */ 3348 1.3 chs if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT)) 3349 1.3 chs newfs = B_TRUE; 3350 1.3 chs 3351 1.1 haad zfs_close(zhp); 3352 1.1 haad } else { 3353 1.1 haad /* 3354 1.1 haad * Destination filesystem does not exist. Therefore we better 3355 1.1 haad * be creating a new filesystem (either from a full backup, or 3356 1.1 haad * a clone). It would therefore be invalid if the user 3357 1.1 haad * specified only the pool name (i.e. if the destination name 3358 1.1 haad * contained no slash character). 3359 1.1 haad */ 3360 1.1 haad if (!stream_wantsnewfs || 3361 1.1 haad (cp = strrchr(zc.zc_name, '/')) == NULL) { 3362 1.1 haad zcmd_free_nvlists(&zc); 3363 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3364 1.1 haad "destination '%s' does not exist"), zc.zc_name); 3365 1.1 haad return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3366 1.1 haad } 3367 1.1 haad 3368 1.1 haad /* 3369 1.1 haad * Trim off the final dataset component so we perform the 3370 1.1 haad * recvbackup ioctl to the filesystems's parent. 3371 1.1 haad */ 3372 1.1 haad *cp = '\0'; 3373 1.1 haad 3374 1.3 chs if (flags->isprefix && !flags->istail && !flags->dryrun && 3375 1.1 haad create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) { 3376 1.1 haad zcmd_free_nvlists(&zc); 3377 1.1 haad return (zfs_error(hdl, EZFS_BADRESTORE, errbuf)); 3378 1.1 haad } 3379 1.1 haad 3380 1.1 haad newfs = B_TRUE; 3381 1.1 haad } 3382 1.1 haad 3383 1.3 chs zc.zc_begin_record = *drr_noswap; 3384 1.1 haad zc.zc_cookie = infd; 3385 1.3 chs zc.zc_guid = flags->force; 3386 1.3 chs zc.zc_resumable = flags->resumable; 3387 1.3 chs if (flags->verbose) { 3388 1.1 haad (void) printf("%s %s stream of %s into %s\n", 3389 1.3 chs flags->dryrun ? "would receive" : "receiving", 3390 1.1 haad drrb->drr_fromguid ? "incremental" : "full", 3391 1.1 haad drrb->drr_toname, zc.zc_value); 3392 1.1 haad (void) fflush(stdout); 3393 1.1 haad } 3394 1.1 haad 3395 1.3 chs if (flags->dryrun) { 3396 1.1 haad zcmd_free_nvlists(&zc); 3397 1.3 chs return (recv_skip(hdl, infd, flags->byteswap)); 3398 1.1 haad } 3399 1.1 haad 3400 1.2 dsl zc.zc_nvlist_dst = (uint64_t)(uintptr_t)prop_errbuf; 3401 1.2 dsl zc.zc_nvlist_dst_size = sizeof (prop_errbuf); 3402 1.3 chs zc.zc_cleanup_fd = cleanup_fd; 3403 1.3 chs zc.zc_action_handle = *action_handlep; 3404 1.2 dsl 3405 1.1 haad err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc); 3406 1.1 haad ioctl_errno = errno; 3407 1.2 dsl prop_errflags = (zprop_errflags_t)zc.zc_obj; 3408 1.2 dsl 3409 1.2 dsl if (err == 0) { 3410 1.2 dsl nvlist_t *prop_errors; 3411 1.2 dsl VERIFY(0 == nvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst, 3412 1.2 dsl zc.zc_nvlist_dst_size, &prop_errors, 0)); 3413 1.2 dsl 3414 1.2 dsl nvpair_t *prop_err = NULL; 3415 1.2 dsl 3416 1.2 dsl while ((prop_err = nvlist_next_nvpair(prop_errors, 3417 1.2 dsl prop_err)) != NULL) { 3418 1.2 dsl char tbuf[1024]; 3419 1.2 dsl zfs_prop_t prop; 3420 1.2 dsl int intval; 3421 1.2 dsl 3422 1.2 dsl prop = zfs_name_to_prop(nvpair_name(prop_err)); 3423 1.2 dsl (void) nvpair_value_int32(prop_err, &intval); 3424 1.2 dsl if (strcmp(nvpair_name(prop_err), 3425 1.2 dsl ZPROP_N_MORE_ERRORS) == 0) { 3426 1.2 dsl trunc_prop_errs(intval); 3427 1.2 dsl break; 3428 1.3 chs } else if (snapname == NULL || finalsnap == NULL || 3429 1.3 chs strcmp(finalsnap, snapname) == 0 || 3430 1.3 chs strcmp(nvpair_name(prop_err), 3431 1.3 chs zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) { 3432 1.3 chs /* 3433 1.3 chs * Skip the special case of, for example, 3434 1.3 chs * "refquota", errors on intermediate 3435 1.3 chs * snapshots leading up to a final one. 3436 1.3 chs * That's why we have all of the checks above. 3437 1.3 chs * 3438 1.3 chs * See zfs_ioctl.c's extract_delay_props() for 3439 1.3 chs * a list of props which can fail on 3440 1.3 chs * intermediate snapshots, but shouldn't 3441 1.3 chs * affect the overall receive. 3442 1.3 chs */ 3443 1.2 dsl (void) snprintf(tbuf, sizeof (tbuf), 3444 1.2 dsl dgettext(TEXT_DOMAIN, 3445 1.2 dsl "cannot receive %s property on %s"), 3446 1.2 dsl nvpair_name(prop_err), zc.zc_name); 3447 1.2 dsl zfs_setprop_error(hdl, prop, intval, tbuf); 3448 1.2 dsl } 3449 1.2 dsl } 3450 1.2 dsl nvlist_free(prop_errors); 3451 1.2 dsl } 3452 1.2 dsl 3453 1.2 dsl zc.zc_nvlist_dst = 0; 3454 1.2 dsl zc.zc_nvlist_dst_size = 0; 3455 1.1 haad zcmd_free_nvlists(&zc); 3456 1.1 haad 3457 1.1 haad if (err == 0 && snapprops_nvlist) { 3458 1.1 haad zfs_cmd_t zc2 = { 0 }; 3459 1.1 haad 3460 1.1 haad (void) strcpy(zc2.zc_name, zc.zc_value); 3461 1.2 dsl zc2.zc_cookie = B_TRUE; /* received */ 3462 1.1 haad if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) { 3463 1.1 haad (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2); 3464 1.1 haad zcmd_free_nvlists(&zc2); 3465 1.1 haad } 3466 1.1 haad } 3467 1.1 haad 3468 1.3 chs if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) { 3469 1.1 haad /* 3470 1.1 haad * It may be that this snapshot already exists, 3471 1.1 haad * in which case we want to consume & ignore it 3472 1.1 haad * rather than failing. 3473 1.1 haad */ 3474 1.1 haad avl_tree_t *local_avl; 3475 1.1 haad nvlist_t *local_nv, *fs; 3476 1.3 chs cp = strchr(zc.zc_value, '@'); 3477 1.1 haad 3478 1.1 haad /* 3479 1.1 haad * XXX Do this faster by just iterating over snaps in 3480 1.1 haad * this fs. Also if zc_value does not exist, we will 3481 1.1 haad * get a strange "does not exist" error message. 3482 1.1 haad */ 3483 1.1 haad *cp = '\0'; 3484 1.2 dsl if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, B_FALSE, 3485 1.3 chs B_FALSE, &local_nv, &local_avl) == 0) { 3486 1.1 haad *cp = '@'; 3487 1.1 haad fs = fsavl_find(local_avl, drrb->drr_toguid, NULL); 3488 1.1 haad fsavl_destroy(local_avl); 3489 1.1 haad nvlist_free(local_nv); 3490 1.1 haad 3491 1.1 haad if (fs != NULL) { 3492 1.3 chs if (flags->verbose) { 3493 1.1 haad (void) printf("snap %s already exists; " 3494 1.1 haad "ignoring\n", zc.zc_value); 3495 1.1 haad } 3496 1.2 dsl err = ioctl_err = recv_skip(hdl, infd, 3497 1.3 chs flags->byteswap); 3498 1.1 haad } 3499 1.1 haad } 3500 1.1 haad *cp = '@'; 3501 1.1 haad } 3502 1.1 haad 3503 1.1 haad if (ioctl_err != 0) { 3504 1.1 haad switch (ioctl_errno) { 3505 1.1 haad case ENODEV: 3506 1.1 haad cp = strchr(zc.zc_value, '@'); 3507 1.1 haad *cp = '\0'; 3508 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3509 1.1 haad "most recent snapshot of %s does not\n" 3510 1.1 haad "match incremental source"), zc.zc_value); 3511 1.1 haad (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf); 3512 1.1 haad *cp = '@'; 3513 1.1 haad break; 3514 1.1 haad case ETXTBSY: 3515 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3516 1.1 haad "destination %s has been modified\n" 3517 1.1 haad "since most recent snapshot"), zc.zc_name); 3518 1.1 haad (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf); 3519 1.1 haad break; 3520 1.1 haad case EEXIST: 3521 1.1 haad cp = strchr(zc.zc_value, '@'); 3522 1.1 haad if (newfs) { 3523 1.1 haad /* it's the containing fs that exists */ 3524 1.1 haad *cp = '\0'; 3525 1.1 haad } 3526 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3527 1.1 haad "destination already exists")); 3528 1.1 haad (void) zfs_error_fmt(hdl, EZFS_EXISTS, 3529 1.1 haad dgettext(TEXT_DOMAIN, "cannot restore to %s"), 3530 1.1 haad zc.zc_value); 3531 1.1 haad *cp = '@'; 3532 1.1 haad break; 3533 1.1 haad case EINVAL: 3534 1.1 haad (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf); 3535 1.1 haad break; 3536 1.1 haad case ECKSUM: 3537 1.3 chs recv_ecksum_set_aux(hdl, zc.zc_value, flags->resumable); 3538 1.3 chs (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf); 3539 1.3 chs break; 3540 1.3 chs case ENOTSUP: 3541 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3542 1.3 chs "pool must be upgraded to receive this stream.")); 3543 1.3 chs (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 3544 1.3 chs break; 3545 1.3 chs case EDQUOT: 3546 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3547 1.3 chs "destination %s space quota exceeded"), zc.zc_name); 3548 1.3 chs (void) zfs_error(hdl, EZFS_NOSPC, errbuf); 3549 1.1 haad break; 3550 1.1 haad default: 3551 1.1 haad (void) zfs_standard_error(hdl, ioctl_errno, errbuf); 3552 1.1 haad } 3553 1.1 haad } 3554 1.1 haad 3555 1.1 haad /* 3556 1.2 dsl * Mount the target filesystem (if created). Also mount any 3557 1.2 dsl * children of the target filesystem if we did a replication 3558 1.2 dsl * receive (indicated by stream_avl being non-NULL). 3559 1.1 haad */ 3560 1.1 haad cp = strchr(zc.zc_value, '@'); 3561 1.1 haad if (cp && (ioctl_err == 0 || !newfs)) { 3562 1.1 haad zfs_handle_t *h; 3563 1.1 haad 3564 1.1 haad *cp = '\0'; 3565 1.1 haad h = zfs_open(hdl, zc.zc_value, 3566 1.1 haad ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); 3567 1.1 haad if (h != NULL) { 3568 1.1 haad if (h->zfs_type == ZFS_TYPE_VOLUME) { 3569 1.1 haad *cp = '@'; 3570 1.2 dsl } else if (newfs || stream_avl) { 3571 1.1 haad /* 3572 1.1 haad * Track the first/top of hierarchy fs, 3573 1.1 haad * for mounting and sharing later. 3574 1.1 haad */ 3575 1.1 haad if (top_zfs && *top_zfs == NULL) 3576 1.1 haad *top_zfs = zfs_strdup(hdl, zc.zc_value); 3577 1.1 haad } 3578 1.1 haad zfs_close(h); 3579 1.1 haad } 3580 1.1 haad *cp = '@'; 3581 1.1 haad } 3582 1.1 haad 3583 1.1 haad if (clp) { 3584 1.3 chs if (!flags->nomount) 3585 1.3 chs err |= changelist_postfix(clp); 3586 1.1 haad changelist_free(clp); 3587 1.1 haad } 3588 1.1 haad 3589 1.2 dsl if (prop_errflags & ZPROP_ERR_NOCLEAR) { 3590 1.2 dsl (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: " 3591 1.2 dsl "failed to clear unreceived properties on %s"), 3592 1.2 dsl zc.zc_name); 3593 1.2 dsl (void) fprintf(stderr, "\n"); 3594 1.2 dsl } 3595 1.2 dsl if (prop_errflags & ZPROP_ERR_NORESTORE) { 3596 1.2 dsl (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: " 3597 1.2 dsl "failed to restore original properties on %s"), 3598 1.2 dsl zc.zc_name); 3599 1.2 dsl (void) fprintf(stderr, "\n"); 3600 1.2 dsl } 3601 1.2 dsl 3602 1.1 haad if (err || ioctl_err) 3603 1.1 haad return (-1); 3604 1.1 haad 3605 1.3 chs *action_handlep = zc.zc_action_handle; 3606 1.3 chs 3607 1.3 chs if (flags->verbose) { 3608 1.1 haad char buf1[64]; 3609 1.1 haad char buf2[64]; 3610 1.1 haad uint64_t bytes = zc.zc_cookie; 3611 1.1 haad time_t delta = time(NULL) - begin_time; 3612 1.1 haad if (delta == 0) 3613 1.1 haad delta = 1; 3614 1.1 haad zfs_nicenum(bytes, buf1, sizeof (buf1)); 3615 1.1 haad zfs_nicenum(bytes/delta, buf2, sizeof (buf1)); 3616 1.1 haad 3617 1.1 haad (void) printf("received %sB stream in %lu seconds (%sB/sec)\n", 3618 1.1 haad buf1, delta, buf2); 3619 1.1 haad } 3620 1.1 haad 3621 1.1 haad return (0); 3622 1.1 haad } 3623 1.1 haad 3624 1.1 haad static int 3625 1.3 chs zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, 3626 1.3 chs const char *originsnap, recvflags_t *flags, int infd, const char *sendfs, 3627 1.3 chs nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd, 3628 1.3 chs uint64_t *action_handlep, const char *finalsnap) 3629 1.1 haad { 3630 1.1 haad int err; 3631 1.1 haad dmu_replay_record_t drr, drr_noswap; 3632 1.1 haad struct drr_begin *drrb = &drr.drr_u.drr_begin; 3633 1.1 haad char errbuf[1024]; 3634 1.1 haad zio_cksum_t zcksum = { 0 }; 3635 1.2 dsl uint64_t featureflags; 3636 1.2 dsl int hdrtype; 3637 1.1 haad 3638 1.1 haad (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3639 1.1 haad "cannot receive")); 3640 1.1 haad 3641 1.3 chs if (flags->isprefix && 3642 1.1 haad !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) { 3643 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs " 3644 1.1 haad "(%s) does not exist"), tosnap); 3645 1.1 haad return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3646 1.1 haad } 3647 1.3 chs if (originsnap && 3648 1.3 chs !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) { 3649 1.3 chs zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs " 3650 1.3 chs "(%s) does not exist"), originsnap); 3651 1.3 chs return (zfs_error(hdl, EZFS_NOENT, errbuf)); 3652 1.3 chs } 3653 1.1 haad 3654 1.1 haad /* read in the BEGIN record */ 3655 1.1 haad if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE, 3656 1.1 haad &zcksum))) 3657 1.1 haad return (err); 3658 1.1 haad 3659 1.1 haad if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) { 3660 1.1 haad /* It's the double end record at the end of a package */ 3661 1.1 haad return (ENODATA); 3662 1.1 haad } 3663 1.1 haad 3664 1.1 haad /* the kernel needs the non-byteswapped begin record */ 3665 1.1 haad drr_noswap = drr; 3666 1.1 haad 3667 1.3 chs flags->byteswap = B_FALSE; 3668 1.1 haad if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) { 3669 1.1 haad /* 3670 1.1 haad * We computed the checksum in the wrong byteorder in 3671 1.1 haad * recv_read() above; do it again correctly. 3672 1.1 haad */ 3673 1.1 haad bzero(&zcksum, sizeof (zio_cksum_t)); 3674 1.1 haad fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum); 3675 1.3 chs flags->byteswap = B_TRUE; 3676 1.1 haad 3677 1.1 haad drr.drr_type = BSWAP_32(drr.drr_type); 3678 1.1 haad drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen); 3679 1.1 haad drrb->drr_magic = BSWAP_64(drrb->drr_magic); 3680 1.2 dsl drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo); 3681 1.1 haad drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time); 3682 1.1 haad drrb->drr_type = BSWAP_32(drrb->drr_type); 3683 1.1 haad drrb->drr_flags = BSWAP_32(drrb->drr_flags); 3684 1.1 haad drrb->drr_toguid = BSWAP_64(drrb->drr_toguid); 3685 1.1 haad drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid); 3686 1.1 haad } 3687 1.1 haad 3688 1.1 haad if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) { 3689 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 3690 1.1 haad "stream (bad magic number)")); 3691 1.1 haad return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 3692 1.1 haad } 3693 1.1 haad 3694 1.2 dsl featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo); 3695 1.2 dsl hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo); 3696 1.2 dsl 3697 1.2 dsl if (!DMU_STREAM_SUPPORTED(featureflags) || 3698 1.2 dsl (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) { 3699 1.2 dsl zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3700 1.2 dsl "stream has unsupported feature, feature flags = %lx"), 3701 1.2 dsl featureflags); 3702 1.2 dsl return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 3703 1.2 dsl } 3704 1.2 dsl 3705 1.1 haad if (strchr(drrb->drr_toname, '@') == NULL) { 3706 1.1 haad zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid " 3707 1.1 haad "stream (bad snapshot name)")); 3708 1.1 haad return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); 3709 1.1 haad } 3710 1.1 haad 3711 1.2 dsl if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) { 3712 1.3 chs char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN]; 3713 1.3 chs if (sendfs == NULL) { 3714 1.3 chs /* 3715 1.3 chs * We were not called from zfs_receive_package(). Get 3716 1.3 chs * the fs specified by 'zfs send'. 3717 1.3 chs */ 3718 1.3 chs char *cp; 3719 1.3 chs (void) strlcpy(nonpackage_sendfs, 3720 1.3 chs drr.drr_u.drr_begin.drr_toname, 3721 1.3 chs sizeof (nonpackage_sendfs)); 3722 1.3 chs if ((cp = strchr(nonpackage_sendfs, '@')) != NULL) 3723 1.3 chs *cp = '\0'; 3724 1.3 chs sendfs = nonpackage_sendfs; 3725 1.3 chs VERIFY(finalsnap == NULL); 3726 1.3 chs } 3727 1.3 chs return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags, 3728 1.3 chs &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs, 3729 1.3 chs cleanup_fd, action_handlep, finalsnap)); 3730 1.3 chs } else { 3731 1.2 dsl assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == 3732 1.2 dsl DMU_COMPOUNDSTREAM); 3733 1.3 chs return (zfs_receive_package(hdl, infd, tosnap, flags, &drr, 3734 1.3 chs &zcksum, top_zfs, cleanup_fd, action_handlep)); 3735 1.1 haad } 3736 1.1 haad } 3737 1.1 haad 3738 1.1 haad /* 3739 1.1 haad * Restores a backup of tosnap from the file descriptor specified by infd. 3740 1.1 haad * Return 0 on total success, -2 if some things couldn't be 3741 1.1 haad * destroyed/renamed/promoted, -1 if some things couldn't be received. 3742 1.3 chs * (-1 will override -2, if -1 and the resumable flag was specified the 3743 1.3 chs * transfer can be resumed if the sending side supports it). 3744 1.1 haad */ 3745 1.1 haad int 3746 1.3 chs zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props, 3747 1.3 chs recvflags_t *flags, int infd, avl_tree_t *stream_avl) 3748 1.1 haad { 3749 1.1 haad char *top_zfs = NULL; 3750 1.1 haad int err; 3751 1.3 chs int cleanup_fd; 3752 1.3 chs uint64_t action_handle = 0; 3753 1.3 chs char *originsnap = NULL; 3754 1.3 chs if (props) { 3755 1.3 chs err = nvlist_lookup_string(props, "origin", &originsnap); 3756 1.3 chs if (err && err != ENOENT) 3757 1.3 chs return (err); 3758 1.3 chs } 3759 1.3 chs 3760 1.3 chs cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL); 3761 1.3 chs VERIFY(cleanup_fd >= 0); 3762 1.3 chs 3763 1.3 chs err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL, 3764 1.3 chs stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL); 3765 1.1 haad 3766 1.3 chs VERIFY(0 == close(cleanup_fd)); 3767 1.1 haad 3768 1.3 chs if (err == 0 && !flags->nomount && top_zfs) { 3769 1.1 haad zfs_handle_t *zhp; 3770 1.1 haad prop_changelist_t *clp; 3771 1.1 haad 3772 1.1 haad zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM); 3773 1.1 haad if (zhp != NULL) { 3774 1.1 haad clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, 3775 1.1 haad CL_GATHER_MOUNT_ALWAYS, 0); 3776 1.1 haad zfs_close(zhp); 3777 1.1 haad if (clp != NULL) { 3778 1.1 haad /* mount and share received datasets */ 3779 1.1 haad err = changelist_postfix(clp); 3780 1.1 haad changelist_free(clp); 3781 1.1 haad } 3782 1.1 haad } 3783 1.1 haad if (zhp == NULL || clp == NULL || err) 3784 1.1 haad err = -1; 3785 1.1 haad } 3786 1.1 haad if (top_zfs) 3787 1.1 haad free(top_zfs); 3788 1.1 haad 3789 1.1 haad return (err); 3790 1.1 haad } 3791