annotate usr/src/lib/libzfs/common/libzfs_sendrecv.c @ 11007:216d8396182e

PSARC/2009/557 ZFS send dedup 6812638 zfs send intra-stream dedup 6887817 want snapshot filtering for zfs send 6812603 zfs send can aggregate free records
author Lori Alt <Lori.Alt@Sun.COM>
date Mon, 09 Nov 2009 11:04:55 -0700
parents dcc7d6f9faa8
children 63ab26072e41
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2 * CDDL HEADER START
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
3 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
4 * The contents of this file are subject to the terms of the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
5 * Common Development and Distribution License (the "License").
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
6 * You may not use this file except in compliance with the License.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
7 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
9 * or http://www.opensolaris.org/os/licensing.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
10 * See the License for the specific language governing permissions
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
11 * and limitations under the License.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
12 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
13 * When distributing Covered Code, include this CDDL HEADER in each
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
15 * If applicable, add the following below this CDDL HEADER, with the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
16 * fields enclosed by brackets "[]" replaced with your own identifying
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
17 * information: Portions Copyright [yyyy] [name of copyright owner]
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
18 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
19 * CDDL HEADER END
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
20 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
21
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
22 /*
8584
327a1b6dd944 6794452 zfs receive can't restore a root pool
Lori Alt <Lori.Alt@Sun.COM>
parents: 7366
diff changeset
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
24 * Use is subject to license terms.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
25 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
26
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
27 #include <assert.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
28 #include <ctype.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
29 #include <errno.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
30 #include <libintl.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
31 #include <stdio.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
32 #include <stdlib.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
33 #include <strings.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
34 #include <unistd.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
35 #include <stddef.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
36 #include <fcntl.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
37 #include <sys/mount.h>
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
38 #include <pthread.h>
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
39 #include <umem.h>
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
40
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
41 #include <libzfs.h>
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
42
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
43 #include "zfs_namecheck.h"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
44 #include "zfs_prop.h"
10602
21d184667b7e 6399128 want tool to examine backup files (zstreamdump)
Lori Alt <Lori.Alt@Sun.COM>
parents: 10588
diff changeset
45 #include "zfs_fletcher.h"
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
46 #include "libzfs_impl.h"
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
47 #include <sha2.h>
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
48
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
49 static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
50 int, avl_tree_t *, char **);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
51
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
52 static const zio_cksum_t zero_cksum = { 0 };
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
53
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
54 typedef struct dedup_arg {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
55 int inputfd;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
56 int outputfd;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
57 libzfs_handle_t *dedup_hdl;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
58 } dedup_arg_t;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
59
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
60 typedef struct dataref {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
61 uint64_t ref_guid;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
62 uint64_t ref_object;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
63 uint64_t ref_offset;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
64 } dataref_t;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
65
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
66 typedef struct dedup_entry {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
67 struct dedup_entry *dde_next;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
68 zio_cksum_t dde_chksum;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
69 dataref_t dde_ref;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
70 } dedup_entry_t;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
71
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
72 #define MAX_DDT_PHYSMEM_PERCENT 20
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
73 #define SMALLEST_POSSIBLE_MAX_DDT_MB 128
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
74
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
75 typedef struct dedup_table {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
76 dedup_entry_t **dedup_hash_array;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
77 umem_cache_t *ddecache;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
78 uint64_t max_ddt_size; /* max dedup table size in bytes */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
79 uint64_t cur_ddt_size; /* current dedup table size in bytes */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
80 uint64_t ddt_count;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
81 int numhashbits;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
82 boolean_t ddt_full;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
83 } dedup_table_t;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
84
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
85 static int
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
86 high_order_bit(uint64_t n)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
87 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
88 int count;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
89
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
90 for (count = 0; n != 0; count++)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
91 n >>= 1;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
92 return (count);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
93 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
94
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
95 static size_t
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
96 ssread(void *buf, size_t len, FILE *stream)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
97 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
98 size_t outlen;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
99
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
100 if ((outlen = fread(buf, len, 1, stream)) == 0)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
101 return (0);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
102
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
103 return (outlen);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
104 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
105
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
106 static void
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
107 ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
108 zio_cksum_t *cs, dataref_t *dr)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
109 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
110 dedup_entry_t *dde;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
111
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
112 if (ddt->cur_ddt_size >= ddt->max_ddt_size) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
113 if (ddt->ddt_full == B_FALSE) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
114 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
115 "Dedup table full. Deduplication will continue "
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
116 "with existing table entries"));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
117 ddt->ddt_full = B_TRUE;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
118 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
119 return;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
120 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
121
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
122 if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT))
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
123 != NULL) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
124 assert(*ddepp == NULL);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
125 dde->dde_next = NULL;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
126 dde->dde_chksum = *cs;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
127 dde->dde_ref = *dr;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
128 *ddepp = dde;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
129 ddt->cur_ddt_size += sizeof (dedup_entry_t);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
130 ddt->ddt_count++;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
131 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
132 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
133
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
134 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
135 * Using the specified dedup table, do a lookup for an entry with
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
136 * the checksum cs. If found, return the block's reference info
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
137 * in *dr. Otherwise, insert a new entry in the dedup table, using
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
138 * the reference information specified by *dr.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
139 *
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
140 * return value: true - entry was found
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
141 * false - entry was not found
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
142 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
143 static boolean_t
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
144 ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
145 dataref_t *dr)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
146 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
147 uint32_t hashcode;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
148 dedup_entry_t **ddepp;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
149
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
150 hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
151
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
152 for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
153 ddepp = &((*ddepp)->dde_next)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
154 if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
155 *dr = (*ddepp)->dde_ref;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
156 return (B_TRUE);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
157 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
158 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
159 ddt_hash_append(hdl, ddt, ddepp, cs, dr);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
160 return (B_FALSE);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
161 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
162
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
163 static int
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
164 cksum_and_write(const void *buf, uint64_t len, zio_cksum_t *zc, int outfd)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
165 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
166 fletcher_4_incremental_native(buf, len, zc);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
167 return (write(outfd, buf, len));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
168 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
169
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
170 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
171 * This function is started in a separate thread when the dedup option
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
172 * has been requested. The main send thread determines the list of
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
173 * snapshots to be included in the send stream and makes the ioctl calls
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
174 * for each one. But instead of having the ioctl send the output to the
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
175 * the output fd specified by the caller of zfs_send()), the
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
176 * ioctl is told to direct the output to a pipe, which is read by the
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
177 * alternate thread running THIS function. This function does the
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
178 * dedup'ing by:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
179 * 1. building a dedup table (the DDT)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
180 * 2. doing checksums on each data block and inserting a record in the DDT
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
181 * 3. looking for matching checksums, and
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
182 * 4. sending a DRR_WRITE_BYREF record instead of a write record whenever
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
183 * a duplicate block is found.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
184 * The output of this function then goes to the output fd requested
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
185 * by the caller of zfs_send().
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
186 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
187 static void *
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
188 cksummer(void *arg)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
189 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
190 dedup_arg_t *dda = arg;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
191 char *buf = malloc(1<<20);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
192 dmu_replay_record_t thedrr;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
193 dmu_replay_record_t *drr = &thedrr;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
194 struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
195 struct drr_end *drre = &thedrr.drr_u.drr_end;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
196 struct drr_object *drro = &thedrr.drr_u.drr_object;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
197 struct drr_write *drrw = &thedrr.drr_u.drr_write;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
198 FILE *ofp;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
199 int outfd;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
200 dmu_replay_record_t wbr_drr;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
201 struct drr_write_byref *wbr_drrr = &wbr_drr.drr_u.drr_write_byref;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
202 dedup_table_t ddt;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
203 zio_cksum_t stream_cksum;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
204 uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
205 uint64_t numbuckets;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
206
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
207 ddt.max_ddt_size =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
208 MAX((physmem * MAX_DDT_PHYSMEM_PERCENT)/100,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
209 SMALLEST_POSSIBLE_MAX_DDT_MB<<20);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
210
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
211 numbuckets = ddt.max_ddt_size/(sizeof (dedup_entry_t));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
212
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
213 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
214 * numbuckets must be a power of 2. Increase number to
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
215 * a power of 2 if necessary.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
216 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
217 if (!ISP2(numbuckets))
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
218 numbuckets = 1 << high_order_bit(numbuckets);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
219
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
220 ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
221 ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
222 NULL, NULL, NULL, NULL, NULL, 0);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
223 ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
224 ddt.numhashbits = high_order_bit(numbuckets) - 1;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
225 ddt.ddt_full = B_FALSE;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
226
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
227 /* Initialize the write-by-reference block. */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
228 wbr_drr.drr_type = DRR_WRITE_BYREF;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
229 wbr_drr.drr_payloadlen = 0;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
230
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
231 outfd = dda->outputfd;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
232 ofp = fdopen(dda->inputfd, "r");
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
233 while (ssread(drr, sizeof (dmu_replay_record_t), ofp) != 0) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
234
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
235 switch (drr->drr_type) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
236 case DRR_BEGIN:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
237 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
238 int fflags;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
239 ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
240
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
241 /* set the DEDUP feature flag for this stream */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
242 fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
243 fflags |= DMU_BACKUP_FEATURE_DEDUP;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
244 DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
245
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
246 if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
247 &stream_cksum, outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
248 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
249 if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
250 DMU_COMPOUNDSTREAM && drr->drr_payloadlen != 0) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
251 int sz = drr->drr_payloadlen;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
252
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
253 if (sz > 1<<20) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
254 free(buf);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
255 buf = malloc(sz);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
256 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
257 (void) ssread(buf, sz, ofp);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
258 if (ferror(stdin))
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
259 perror("fread");
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
260 if (cksum_and_write(buf, sz, &stream_cksum,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
261 outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
262 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
263 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
264 break;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
265 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
266
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
267 case DRR_END:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
268 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
269 /* use the recalculated checksum */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
270 ZIO_SET_CHECKSUM(&drre->drr_checksum,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
271 stream_cksum.zc_word[0], stream_cksum.zc_word[1],
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
272 stream_cksum.zc_word[2], stream_cksum.zc_word[3]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
273 if ((write(outfd, drr,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
274 sizeof (dmu_replay_record_t))) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
275 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
276 break;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
277 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
278
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
279 case DRR_OBJECT:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
280 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
281 if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
282 &stream_cksum, outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
283 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
284 if (drro->drr_bonuslen > 0) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
285 (void) ssread(buf,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
286 P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
287 ofp);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
288 if (cksum_and_write(buf,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
289 P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
290 &stream_cksum, outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
291 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
292 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
293 break;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
294 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
295
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
296 case DRR_FREEOBJECTS:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
297 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
298 if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
299 &stream_cksum, outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
300 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
301 break;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
302 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
303
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
304 case DRR_WRITE:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
305 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
306 dataref_t dataref;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
307
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
308 (void) ssread(buf, drrw->drr_length, ofp);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
309 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
310 * If the block doesn't already have a dedup
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
311 * checksum, calculate one.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
312 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
313 if (ZIO_CHECKSUM_EQUAL(drrw->drr_blkcksum,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
314 zero_cksum)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
315 SHA256_CTX ctx;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
316 zio_cksum_t tmpsha256;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
317
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
318 SHA256Init(&ctx);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
319 SHA256Update(&ctx, buf, drrw->drr_length);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
320 SHA256Final(&tmpsha256, &ctx);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
321 drrw->drr_blkcksum.zc_word[0] =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
322 BE_64(tmpsha256.zc_word[0]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
323 drrw->drr_blkcksum.zc_word[1] =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
324 BE_64(tmpsha256.zc_word[1]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
325 drrw->drr_blkcksum.zc_word[2] =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
326 BE_64(tmpsha256.zc_word[2]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
327 drrw->drr_blkcksum.zc_word[3] =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
328 BE_64(tmpsha256.zc_word[3]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
329 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
330
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
331 dataref.ref_guid = drrw->drr_toguid;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
332 dataref.ref_object = drrw->drr_object;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
333 dataref.ref_offset = drrw->drr_offset;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
334
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
335 if (ddt_update(dda->dedup_hdl, &ddt,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
336 &drrw->drr_blkcksum, &dataref)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
337 /* block already present in stream */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
338 wbr_drrr->drr_object = drrw->drr_object;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
339 wbr_drrr->drr_offset = drrw->drr_offset;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
340 wbr_drrr->drr_length = drrw->drr_length;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
341 wbr_drrr->drr_toguid = drrw->drr_toguid;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
342 wbr_drrr->drr_refguid = dataref.ref_guid;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
343 wbr_drrr->drr_refobject =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
344 dataref.ref_object;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
345 wbr_drrr->drr_refoffset =
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
346 dataref.ref_offset;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
347
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
348 wbr_drrr->drr_blkcksum = drrw->drr_blkcksum;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
349
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
350 if (cksum_and_write(&wbr_drr,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
351 sizeof (dmu_replay_record_t), &stream_cksum,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
352 outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
353 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
354 } else {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
355 /* block not previously seen */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
356 if (cksum_and_write(drr,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
357 sizeof (dmu_replay_record_t), &stream_cksum,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
358 outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
359 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
360 if (cksum_and_write(buf,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
361 drrw->drr_length,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
362 &stream_cksum, outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
363 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
364 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
365 break;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
366 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
367
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
368 case DRR_FREE:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
369 {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
370 if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
371 &stream_cksum, outfd) == -1)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
372 goto out;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
373 break;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
374 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
375
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
376 default:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
377 (void) printf("INVALID record type 0x%x\n",
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
378 drr->drr_type);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
379 /* should never happen, so assert */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
380 assert(B_FALSE);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
381 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
382 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
383 out:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
384 umem_cache_destroy(ddt.ddecache);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
385 free(ddt.dedup_hash_array);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
386 free(buf);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
387 (void) fclose(ofp);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
388
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
389 return (NULL);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
390 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
391
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
392 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
393 * Routines for dealing with the AVL tree of fs-nvlists
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
394 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
395 typedef struct fsavl_node {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
396 avl_node_t fn_node;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
397 nvlist_t *fn_nvfs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
398 char *fn_snapname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
399 uint64_t fn_guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
400 } fsavl_node_t;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
401
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
402 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
403 fsavl_compare(const void *arg1, const void *arg2)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
404 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
405 const fsavl_node_t *fn1 = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
406 const fsavl_node_t *fn2 = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
407
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
408 if (fn1->fn_guid > fn2->fn_guid)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
409 return (+1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
410 else if (fn1->fn_guid < fn2->fn_guid)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
411 return (-1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
412 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
413 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
414 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
415
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
416 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
417 * Given the GUID of a snapshot, find its containing filesystem and
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
418 * (optionally) name.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
419 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
420 static nvlist_t *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
421 fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
422 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
423 fsavl_node_t fn_find;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
424 fsavl_node_t *fn;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
425
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
426 fn_find.fn_guid = snapguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
427
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
428 fn = avl_find(avl, &fn_find, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
429 if (fn) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
430 if (snapname)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
431 *snapname = fn->fn_snapname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
432 return (fn->fn_nvfs);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
433 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
434 return (NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
435 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
436
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
437 static void
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
438 fsavl_destroy(avl_tree_t *avl)
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
439 {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
440 fsavl_node_t *fn;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
441 void *cookie;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
442
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
443 if (avl == NULL)
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
444 return;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
445
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
446 cookie = NULL;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
447 while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
448 free(fn);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
449 avl_destroy(avl);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
450 free(avl);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
451 }
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
452
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
453 /*
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
454 * Given an nvlist, produce an avl tree of snapshots, ordered by guid
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
455 */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
456 static avl_tree_t *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
457 fsavl_create(nvlist_t *fss)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
458 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
459 avl_tree_t *fsavl;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
460 nvpair_t *fselem = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
461
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
462 if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
463 return (NULL);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
464
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
465 avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
466 offsetof(fsavl_node_t, fn_node));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
467
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
468 while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
469 nvlist_t *nvfs, *snaps;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
470 nvpair_t *snapelem = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
471
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
472 VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
473 VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
474
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
475 while ((snapelem =
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
476 nvlist_next_nvpair(snaps, snapelem)) != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
477 fsavl_node_t *fn;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
478 uint64_t guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
479
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
480 VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
481 if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
482 fsavl_destroy(fsavl);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
483 return (NULL);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
484 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
485 fn->fn_nvfs = nvfs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
486 fn->fn_snapname = nvpair_name(snapelem);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
487 fn->fn_guid = guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
488
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
489 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
490 * Note: if there are multiple snaps with the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
491 * same GUID, we ignore all but one.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
492 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
493 if (avl_find(fsavl, fn, NULL) == NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
494 avl_add(fsavl, fn);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
495 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
496 free(fn);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
497 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
498 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
499
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
500 return (fsavl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
501 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
502
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
503 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
504 * Routines for dealing with the giant nvlist of fs-nvlists, etc.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
505 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
506 typedef struct send_data {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
507 uint64_t parent_fromsnap_guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
508 nvlist_t *parent_snaps;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
509 nvlist_t *fss;
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
510 nvlist_t *snapprops;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
511 const char *fromsnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
512 const char *tosnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
513
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
514 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
515 * The header nvlist is of the following format:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
516 * {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
517 * "tosnap" -> string
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
518 * "fromsnap" -> string (if incremental)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
519 * "fss" -> {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
520 * id -> {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
521 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
522 * "name" -> string (full name; for debugging)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
523 * "parentfromsnap" -> number (guid of fromsnap in parent)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
524 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
525 * "props" -> { name -> value (only if set here) }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
526 * "snaps" -> { name (lastname) -> number (guid) }
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
527 * "snapprops" -> { name (lastname) -> { name -> value } }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
528 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
529 * "origin" -> number (guid) (if clone)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
530 * "sent" -> boolean (not on-disk)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
531 * }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
532 * }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
533 * }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
534 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
535 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
536 } send_data_t;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
537
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
538 static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
539
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
540 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
541 send_iterate_snap(zfs_handle_t *zhp, void *arg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
542 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
543 send_data_t *sd = arg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
544 uint64_t guid = zhp->zfs_dmustats.dds_guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
545 char *snapname;
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
546 nvlist_t *nv;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
547
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
548 snapname = strrchr(zhp->zfs_name, '@')+1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
549
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
550 VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
551 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
552 * NB: if there is no fromsnap here (it's a newly created fs in
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
553 * an incremental replication), we will substitute the tosnap.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
554 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
555 if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) ||
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
556 (sd->parent_fromsnap_guid == 0 && sd->tosnap &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
557 strcmp(snapname, sd->tosnap) == 0)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
558 sd->parent_fromsnap_guid = guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
559 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
560
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
561 VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
562 send_iterate_prop(zhp, nv);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
563 VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
564 nvlist_free(nv);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
565
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
566 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
567 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
568 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
569
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
570 static void
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
571 send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
572 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
573 nvpair_t *elem = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
574
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
575 while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
576 char *propname = nvpair_name(elem);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
577 zfs_prop_t prop = zfs_name_to_prop(propname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
578 nvlist_t *propnv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
579
10960
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
580 if (!zfs_prop_user(propname)) {
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
581 /*
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
582 * Realistically, this should never happen. However,
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
583 * we want the ability to add DSL properties without
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
584 * needing to make incompatible version changes. We
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
585 * need to ignore unknown properties to allow older
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
586 * software to still send datasets containing these
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
587 * properties, with the unknown properties elided.
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
588 */
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
589 if (prop == ZPROP_INVAL)
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
590 continue;
9396
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
591
10960
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
592 if (zfs_prop_readonly(prop))
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
593 continue;
dcc7d6f9faa8 6897978 zfs send should ignore unknown properties
Eric Schrock <Eric.Schrock@Sun.COM>
parents: 10735
diff changeset
594 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
595
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
596 verify(nvpair_value_nvlist(elem, &propnv) == 0);
10195
f194519c90bf 6853862 refquota property not send over with zfs send -R
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
597 if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION ||
f194519c90bf 6853862 refquota property not send over with zfs send -R
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
598 prop == ZFS_PROP_REFQUOTA ||
f194519c90bf 6853862 refquota property not send over with zfs send -R
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 9396
diff changeset
599 prop == ZFS_PROP_REFRESERVATION) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
600 /* these guys are modifyable, but have no source */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
601 uint64_t value;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
602 verify(nvlist_lookup_uint64(propnv,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
603 ZPROP_VALUE, &value) == 0);
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
604 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
605 continue;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
606 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
607 char *source;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
608 if (nvlist_lookup_string(propnv,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
609 ZPROP_SOURCE, &source) != 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
610 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
611 if (strcmp(source, zhp->zfs_name) != 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
612 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
613 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
614
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
615 if (zfs_prop_user(propname) ||
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
616 zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
617 char *value;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
618 verify(nvlist_lookup_string(propnv,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
619 ZPROP_VALUE, &value) == 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
620 VERIFY(0 == nvlist_add_string(nv, propname, value));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
621 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
622 uint64_t value;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
623 verify(nvlist_lookup_uint64(propnv,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
624 ZPROP_VALUE, &value) == 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
625 VERIFY(0 == nvlist_add_uint64(nv, propname, value));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
626 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
627 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
628 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
629
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
630 /*
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
631 * recursively generate nvlists describing datasets. See comment
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
632 * for the data structure send_data_t above for description of contents
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
633 * of the nvlist.
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
634 */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
635 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
636 send_iterate_fs(zfs_handle_t *zhp, void *arg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
637 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
638 send_data_t *sd = arg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
639 nvlist_t *nvfs, *nv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
640 int rv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
641 uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
642 uint64_t guid = zhp->zfs_dmustats.dds_guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
643 char guidstring[64];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
644
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
645 VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
646 VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
647 VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
648 sd->parent_fromsnap_guid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
649
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
650 if (zhp->zfs_dmustats.dds_origin[0]) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
651 zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
652 zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
653 if (origin == NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
654 return (-1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
655 VERIFY(0 == nvlist_add_uint64(nvfs, "origin",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
656 origin->zfs_dmustats.dds_guid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
657 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
658
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
659 /* iterate over props */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
660 VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
661 send_iterate_prop(zhp, nv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
662 VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
663 nvlist_free(nv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
664
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
665 /* iterate over snaps, and set sd->parent_fromsnap_guid */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
666 sd->parent_fromsnap_guid = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
667 VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
668 VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
669 (void) zfs_iter_snapshots(zhp, send_iterate_snap, sd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
670 VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
671 VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
672 nvlist_free(sd->parent_snaps);
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
673 nvlist_free(sd->snapprops);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
674
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
675 /* add this fs to nvlist */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
676 (void) snprintf(guidstring, sizeof (guidstring),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
677 "0x%llx", (longlong_t)guid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
678 VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
679 nvlist_free(nvfs);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
680
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
681 /* iterate over children */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
682 rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
683
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
684 sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
685
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
686 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
687 return (rv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
688 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
689
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
690 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
691 gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
692 const char *tosnap, nvlist_t **nvlp, avl_tree_t **avlp)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
693 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
694 zfs_handle_t *zhp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
695 send_data_t sd = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
696 int error;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
697
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
698 zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
699 if (zhp == NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
700 return (EZFS_BADTYPE);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
701
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
702 VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
703 sd.fromsnap = fromsnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
704 sd.tosnap = tosnap;
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
705
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
706 if ((error = send_iterate_fs(zhp, &sd)) != 0) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
707 nvlist_free(sd.fss);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
708 if (avlp != NULL)
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
709 *avlp = NULL;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
710 *nvlp = NULL;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
711 return (error);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
712 }
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
713
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
714 if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
715 nvlist_free(sd.fss);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
716 *nvlp = NULL;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
717 return (EZFS_NOMEM);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
718 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
719
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
720 *nvlp = sd.fss;
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
721 return (0);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
722 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
723
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
724 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
725 * Routines for dealing with the sorted snapshot functionality
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
726 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
727 typedef struct zfs_node {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
728 zfs_handle_t *zn_handle;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
729 avl_node_t zn_avlnode;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
730 } zfs_node_t;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
731
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
732 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
733 zfs_sort_snaps(zfs_handle_t *zhp, void *data)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
734 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
735 avl_tree_t *avl = data;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
736 zfs_node_t *node = zfs_alloc(zhp->zfs_hdl, sizeof (zfs_node_t));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
737
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
738 node->zn_handle = zhp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
739 avl_add(avl, node);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
740 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
741 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
742
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
743 /* ARGSUSED */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
744 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
745 zfs_snapshot_compare(const void *larg, const void *rarg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
746 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
747 zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
748 zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
749 uint64_t lcreate, rcreate;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
750
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
751 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
752 * Sort them according to creation time. We use the hidden
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
753 * CREATETXG property to get an absolute ordering of snapshots.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
754 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
755 lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
756 rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
757
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
758 if (lcreate < rcreate)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
759 return (-1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
760 else if (lcreate > rcreate)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
761 return (+1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
762 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
763 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
764 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
765
10342
108f0058f837 6833815 scheduled snapshots deleted per snapshot policy can lead to replication failures
Chris Kirby <chris.kirby@sun.com>
parents: 10302
diff changeset
766 int
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
767 zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
768 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
769 int ret = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
770 zfs_node_t *node;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
771 avl_tree_t avl;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
772 void *cookie = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
773
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
774 avl_create(&avl, zfs_snapshot_compare,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
775 sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
776
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
777 ret = zfs_iter_snapshots(zhp, zfs_sort_snaps, &avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
778
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
779 for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
780 ret |= callback(node->zn_handle, data);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
781
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
782 while ((node = avl_destroy_nodes(&avl, &cookie)) != NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
783 free(node);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
784
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
785 avl_destroy(&avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
786
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
787 return (ret);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
788 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
789
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
790 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
791 * Routines specific to "zfs send"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
792 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
793 typedef struct send_dump_data {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
794 /* these are all just the short snapname (the part after the @) */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
795 const char *fromsnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
796 const char *tosnap;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
797 char prevsnap[ZFS_MAXNAMELEN];
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
798 boolean_t seenfrom, seento, replicate, doall, fromorigin;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
799 boolean_t verbose;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
800 int outfd;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
801 boolean_t err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
802 nvlist_t *fss;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
803 avl_tree_t *fsavl;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
804 snapfilter_cb_t *filter_cb;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
805 void *filter_cb_arg;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
806 } send_dump_data_t;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
807
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
808 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
809 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
810 * NULL) to the file descriptor specified by outfd.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
811 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
812 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
813 dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
814 int outfd)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
815 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
816 zfs_cmd_t zc = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
817 libzfs_handle_t *hdl = zhp->zfs_hdl;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
818
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
819 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
820 assert(fromsnap == NULL || fromsnap[0] == '\0' || !fromorigin);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
821
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
822 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
823 if (fromsnap)
5765
86c482ef4a34 6646545 Condvars in tx_cpu aren't being initialized/destroyed
ek110237
parents: 5446
diff changeset
824 (void) strlcpy(zc.zc_value, fromsnap, sizeof (zc.zc_value));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
825 zc.zc_cookie = outfd;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
826 zc.zc_obj = fromorigin;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
827
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
828 if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SEND, &zc) != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
829 char errbuf[1024];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
830 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
831 "warning: cannot send '%s'"), zhp->zfs_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
832
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
833 switch (errno) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
834
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
835 case EXDEV:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
836 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
837 "not an earlier snapshot from the same fs"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
838 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
839
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
840 case ENOENT:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
841 if (zfs_dataset_exists(hdl, zc.zc_name,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
842 ZFS_TYPE_SNAPSHOT)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
843 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
844 "incremental source (@%s) does not exist"),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
845 zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
846 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
847 return (zfs_error(hdl, EZFS_NOENT, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
848
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
849 case EDQUOT:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
850 case EFBIG:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
851 case EIO:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
852 case ENOLINK:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
853 case ENOSPC:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
854 case ENOSTR:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
855 case ENXIO:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
856 case EPIPE:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
857 case ERANGE:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
858 case EFAULT:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
859 case EROFS:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
860 zfs_error_aux(hdl, strerror(errno));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
861 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
862
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
863 default:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
864 return (zfs_standard_error(hdl, errno, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
865 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
866 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
867
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
868 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
869 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
870
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
871 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
872 dump_snapshot(zfs_handle_t *zhp, void *arg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
873 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
874 send_dump_data_t *sdd = arg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
875 const char *thissnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
876 int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
877
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
878 thissnap = strchr(zhp->zfs_name, '@') + 1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
879
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
880 if (sdd->fromsnap && !sdd->seenfrom &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
881 strcmp(sdd->fromsnap, thissnap) == 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
882 sdd->seenfrom = B_TRUE;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
883 (void) strcpy(sdd->prevsnap, thissnap);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
884 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
885 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
886 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
887
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
888 if (sdd->seento || !sdd->seenfrom) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
889 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
890 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
891 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
892
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
893 if (strcmp(sdd->tosnap, thissnap) == 0)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
894 sdd->seento = B_TRUE;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
895
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
896 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
897 * If a filter function exists, call it to determine whether
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
898 * this snapshot will be sent.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
899 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
900 if (sdd->filter_cb != NULL &&
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
901 sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
902 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
903 * This snapshot is filtered out. Don't send it, and don't
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
904 * set prevsnap, so it will be as if this snapshot didn't
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
905 * exist, and the next accepted snapshot will be sent as
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
906 * an incremental from the last accepted one, or as the
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
907 * first (and full) snapshot in the case of a replication,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
908 * non-incremental send.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
909 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
910 zfs_close(zhp);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
911 return (0);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
912 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
913
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
914 /* send it */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
915 if (sdd->verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
916 (void) fprintf(stderr, "sending from @%s to %s\n",
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
917 sdd->prevsnap, zhp->zfs_name);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
918 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
919
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
920 err = dump_ioctl(zhp, sdd->prevsnap,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
921 sdd->prevsnap[0] == '\0' && (sdd->fromorigin || sdd->replicate),
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
922 sdd->outfd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
923
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
924 (void) strcpy(sdd->prevsnap, thissnap);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
925 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
926 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
927 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
928
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
929 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
930 dump_filesystem(zfs_handle_t *zhp, void *arg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
931 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
932 int rv = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
933 send_dump_data_t *sdd = arg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
934 boolean_t missingfrom = B_FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
935 zfs_cmd_t zc = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
936
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
937 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
938 zhp->zfs_name, sdd->tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
939 if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
940 (void) fprintf(stderr, "WARNING: "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
941 "could not send %s@%s: does not exist\n",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
942 zhp->zfs_name, sdd->tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
943 sdd->err = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
944 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
945 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
946
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
947 if (sdd->replicate && sdd->fromsnap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
948 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
949 * If this fs does not have fromsnap, and we're doing
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
950 * recursive, we need to send a full stream from the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
951 * beginning (or an incremental from the origin if this
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
952 * is a clone). If we're doing non-recursive, then let
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
953 * them get the error.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
954 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
955 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
956 zhp->zfs_name, sdd->fromsnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
957 if (ioctl(zhp->zfs_hdl->libzfs_fd,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
958 ZFS_IOC_OBJSET_STATS, &zc) != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
959 missingfrom = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
960 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
961 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
962
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
963 if (sdd->doall) {
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
964 sdd->seenfrom = sdd->seento = sdd->prevsnap[0] = 0;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
965 if (sdd->fromsnap == NULL || missingfrom)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
966 sdd->seenfrom = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
967
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
968 rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
969 if (!sdd->seenfrom) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
970 (void) fprintf(stderr,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
971 "WARNING: could not send %s@%s:\n"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
972 "incremental source (%s@%s) does not exist\n",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
973 zhp->zfs_name, sdd->tosnap,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
974 zhp->zfs_name, sdd->fromsnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
975 sdd->err = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
976 } else if (!sdd->seento) {
9396
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
977 if (sdd->fromsnap) {
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
978 (void) fprintf(stderr,
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
979 "WARNING: could not send %s@%s:\n"
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
980 "incremental source (%s@%s) "
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
981 "is not earlier than it\n",
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
982 zhp->zfs_name, sdd->tosnap,
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
983 zhp->zfs_name, sdd->fromsnap);
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
984 } else {
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
985 (void) fprintf(stderr, "WARNING: "
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
986 "could not send %s@%s: does not exist\n",
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
987 zhp->zfs_name, sdd->tosnap);
f41cf682d0d3 PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 8584
diff changeset
988 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
989 sdd->err = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
990 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
991 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
992 zfs_handle_t *snapzhp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
993 char snapname[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
994
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
995 (void) snprintf(snapname, sizeof (snapname), "%s@%s",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
996 zfs_get_name(zhp), sdd->tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
997 snapzhp = zfs_open(zhp->zfs_hdl, snapname, ZFS_TYPE_SNAPSHOT);
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
998 if (snapzhp == NULL) {
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
999 rv = -1;
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1000 } else {
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1001 if (sdd->filter_cb == NULL ||
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1002 sdd->filter_cb(snapzhp, sdd->filter_cb_arg) ==
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1003 B_TRUE) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1004 rv = dump_ioctl(snapzhp,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1005 missingfrom ? NULL : sdd->fromsnap,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1006 sdd->fromorigin || missingfrom,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1007 sdd->outfd);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1008 }
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1009 sdd->seento = B_TRUE;
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1010 zfs_close(snapzhp);
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1011 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1012 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1013
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1014 return (rv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1015 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1016
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1017 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1018 dump_filesystems(zfs_handle_t *rzhp, void *arg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1019 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1020 send_dump_data_t *sdd = arg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1021 nvpair_t *fspair;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1022 boolean_t needagain, progress;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1023
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1024 if (!sdd->replicate)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1025 return (dump_filesystem(rzhp, sdd));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1026
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1027 again:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1028 needagain = progress = B_FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1029 for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1030 fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1031 nvlist_t *fslist;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1032 char *fsname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1033 zfs_handle_t *zhp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1034 int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1035 uint64_t origin_guid = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1036 nvlist_t *origin_nv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1037
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1038 VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1039 if (nvlist_lookup_boolean(fslist, "sent") == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1040 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1041
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1042 VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1043 (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1044
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1045 origin_nv = fsavl_find(sdd->fsavl, origin_guid, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1046 if (origin_nv &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1047 nvlist_lookup_boolean(origin_nv, "sent") == ENOENT) {
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1048 /*
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1049 * origin has not been sent yet;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1050 * skip this clone.
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1051 */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1052 needagain = B_TRUE;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1053 continue;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1054 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1055
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1056 zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1057 if (zhp == NULL)
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1058 return (-1);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1059 err = dump_filesystem(zhp, sdd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1060 VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1061 progress = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1062 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1063 if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1064 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1065 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1066 if (needagain) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1067 assert(progress);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1068 goto again;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1069 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1070 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1071 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1072
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1073 /*
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1074 * Generate a send stream for the dataset identified by the argument zhp.
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1075 *
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1076 * The content of the send stream is the snapshot identified by
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1077 * 'tosnap'. Incremental streams are requested in two ways:
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1078 * - from the snapshot identified by "fromsnap" (if non-null) or
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1079 * - from the origin of the dataset identified by zhp, which must
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1080 * be a clone. In this case, "fromsnap" is null and "fromorigin"
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1081 * is TRUE.
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1082 *
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1083 * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1084 * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1085 * if "replicate" is set. If "doall" is set, dump all the intermediate
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1086 * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
1087 * case too.
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1088 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1089 int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1090 zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1091 sendflags_t flags, int outfd, snapfilter_cb_t filter_func,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1092 void *cb_arg)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1093 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1094 char errbuf[1024];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1095 send_dump_data_t sdd = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1096 int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1097 nvlist_t *fss = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1098 avl_tree_t *fsavl = NULL;
10342
108f0058f837 6833815 scheduled snapshots deleted per snapshot policy can lead to replication failures
Chris Kirby <chris.kirby@sun.com>
parents: 10302
diff changeset
1099 char holdtag[128];
108f0058f837 6833815 scheduled snapshots deleted per snapshot policy can lead to replication failures
Chris Kirby <chris.kirby@sun.com>
parents: 10302
diff changeset
1100 static uint64_t holdseq;
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1101 int spa_version;
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1102 boolean_t holdsnaps = B_FALSE;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1103 pthread_t tid;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1104 int pipefd[2];
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1105 dedup_arg_t dda = { 0 };
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1106 int featureflags = 0;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1107
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1108 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1109 "cannot send '%s'"), zhp->zfs_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1110
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1111 if (fromsnap && fromsnap[0] == '\0') {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1112 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1113 "zero-length incremental source"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1114 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1115 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1116
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1117 if (zfs_spa_version(zhp, &spa_version) == 0 &&
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1118 spa_version >= SPA_VERSION_USERREFS)
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1119 holdsnaps = B_TRUE;
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1120
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1121 if (flags.dedup) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1122 featureflags |= DMU_BACKUP_FEATURE_DEDUP;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1123 if (err = pipe(pipefd)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1124 zfs_error_aux(zhp->zfs_hdl, strerror(errno));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1125 return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1126 errbuf));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1127 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1128 dda.outputfd = outfd;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1129 dda.inputfd = pipefd[1];
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1130 dda.dedup_hdl = zhp->zfs_hdl;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1131 if (err = pthread_create(&tid, NULL, cksummer, &dda)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1132 (void) close(pipefd[0]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1133 (void) close(pipefd[1]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1134 zfs_error_aux(zhp->zfs_hdl, strerror(errno));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1135 return (zfs_error(zhp->zfs_hdl,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1136 EZFS_THREADCREATEFAILED, errbuf));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1137 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1138 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1139
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1140 if (flags.replicate || flags.doall) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1141 dmu_replay_record_t drr = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1142 char *packbuf = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1143 size_t buflen = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1144 zio_cksum_t zc = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1145
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1146 assert(fromsnap || flags.doall);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1147
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1148 if (holdsnaps) {
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1149 (void) snprintf(holdtag, sizeof (holdtag),
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1150 ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1151 ++holdseq;
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1152 err = zfs_hold_range(zhp, fromsnap, tosnap,
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1153 holdtag, B_TRUE);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1154 if (err)
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1155 goto err_out;
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1156 }
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1157
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1158
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1159 if (flags.replicate) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1160 nvlist_t *hdrnv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1161
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1162 VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1163 if (fromsnap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1164 VERIFY(0 == nvlist_add_string(hdrnv,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1165 "fromsnap", fromsnap));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1166 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1167 VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1168
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1169 err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1170 fromsnap, tosnap, &fss, &fsavl);
10342
108f0058f837 6833815 scheduled snapshots deleted per snapshot policy can lead to replication failures
Chris Kirby <chris.kirby@sun.com>
parents: 10302
diff changeset
1171 if (err) {
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1172 if (holdsnaps) {
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1173 (void) zfs_release_range(zhp, fromsnap,
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1174 tosnap, holdtag);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1175 }
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1176 goto err_out;
10342
108f0058f837 6833815 scheduled snapshots deleted per snapshot policy can lead to replication failures
Chris Kirby <chris.kirby@sun.com>
parents: 10302
diff changeset
1177 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1178 VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1179 err = nvlist_pack(hdrnv, &packbuf, &buflen,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1180 NV_ENCODE_XDR, 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1181 nvlist_free(hdrnv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1182 if (err) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1183 fsavl_destroy(fsavl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1184 nvlist_free(fss);
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1185 if (holdsnaps) {
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1186 (void) zfs_release_range(zhp, fromsnap,
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1187 tosnap, holdtag);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1188 }
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1189 goto stderr_out;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1190 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1191 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1192
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1193 /* write first begin record */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1194 drr.drr_type = DRR_BEGIN;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1195 drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1196 DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.drr_versioninfo,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1197 DMU_COMPOUNDSTREAM);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1198 DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.drr_versioninfo,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1199 featureflags);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1200 (void) snprintf(drr.drr_u.drr_begin.drr_toname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1201 sizeof (drr.drr_u.drr_begin.drr_toname),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1202 "%s@%s", zhp->zfs_name, tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1203 drr.drr_payloadlen = buflen;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1204 err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1205
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1206 /* write header nvlist */
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1207 if (err != -1 && flags.replicate) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1208 err = cksum_and_write(packbuf, buflen, &zc, outfd);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1209 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1210 free(packbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1211 if (err == -1) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1212 fsavl_destroy(fsavl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1213 nvlist_free(fss);
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1214 if (holdsnaps) {
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1215 (void) zfs_release_range(zhp, fromsnap, tosnap,
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1216 holdtag);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1217 }
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1218 err = errno;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1219 goto stderr_out;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1220 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1221
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1222 /* write end record */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1223 if (err != -1) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1224 bzero(&drr, sizeof (drr));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1225 drr.drr_type = DRR_END;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1226 drr.drr_u.drr_end.drr_checksum = zc;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1227 err = write(outfd, &drr, sizeof (drr));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1228 if (err == -1) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1229 fsavl_destroy(fsavl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1230 nvlist_free(fss);
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1231 if (holdsnaps) {
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1232 (void) zfs_release_range(zhp, fromsnap,
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1233 tosnap, holdtag);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1234 }
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1235 err = errno;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1236 goto stderr_out;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1237 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1238 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1239 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1240
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1241 /* dump each stream */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1242 sdd.fromsnap = fromsnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1243 sdd.tosnap = tosnap;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1244 if (flags.dedup)
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1245 sdd.outfd = pipefd[0];
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1246 else
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1247 sdd.outfd = outfd;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1248 sdd.replicate = flags.replicate;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1249 sdd.doall = flags.doall;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1250 sdd.fromorigin = flags.fromorigin;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1251 sdd.fss = fss;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1252 sdd.fsavl = fsavl;
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1253 sdd.verbose = flags.verbose;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1254 sdd.filter_cb = filter_func;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1255 sdd.filter_cb_arg = cb_arg;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1256 err = dump_filesystems(zhp, &sdd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1257 fsavl_destroy(fsavl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1258 nvlist_free(fss);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1259
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1260 if (flags.dedup) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1261 (void) close(pipefd[0]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1262 (void) pthread_join(tid, NULL);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1263 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1264 if (flags.replicate || flags.doall) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1265 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1266 * write final end record. NB: want to do this even if
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1267 * there was some error, because it might not be totally
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1268 * failed.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1269 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1270 dmu_replay_record_t drr = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1271 drr.drr_type = DRR_END;
10735
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1272 if (holdsnaps) {
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1273 (void) zfs_release_range(zhp, fromsnap, tosnap,
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1274 holdtag);
336fb268ea6f 6885860 zfs send shouldn't require support for snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10602
diff changeset
1275 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1276 if (write(outfd, &drr, sizeof (drr)) == -1) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1277 return (zfs_standard_error(zhp->zfs_hdl,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1278 errno, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1279 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1280 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1281
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1282 return (err || sdd.err);
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1283
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1284 stderr_out:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1285 err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1286 err_out:
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1287 if (flags.dedup) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1288 (void) pthread_cancel(tid);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1289 (void) pthread_join(tid, NULL);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1290 (void) close(pipefd[0]);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1291 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1292 return (err);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1293 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1294
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1295 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1296 * Routines specific to "zfs recv"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1297 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1298
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1299 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1300 recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1301 boolean_t byteswap, zio_cksum_t *zc)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1302 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1303 char *cp = buf;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1304 int rv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1305 int len = ilen;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1306
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1307 do {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1308 rv = read(fd, cp, len);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1309 cp += rv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1310 len -= rv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1311 } while (rv > 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1312
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1313 if (rv < 0 || len != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1314 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1315 "failed to read from stream"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1316 return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1317 "cannot receive")));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1318 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1319
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1320 if (zc) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1321 if (byteswap)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1322 fletcher_4_incremental_byteswap(buf, ilen, zc);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1323 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1324 fletcher_4_incremental_native(buf, ilen, zc);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1325 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1326 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1327 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1328
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1329 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1330 recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1331 boolean_t byteswap, zio_cksum_t *zc)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1332 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1333 char *buf;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1334 int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1335
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1336 buf = zfs_alloc(hdl, len);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1337 if (buf == NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1338 return (ENOMEM);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1339
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1340 err = recv_read(hdl, fd, buf, len, byteswap, zc);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1341 if (err != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1342 free(buf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1343 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1344 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1345
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1346 err = nvlist_unpack(buf, len, nvp, 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1347 free(buf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1348 if (err != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1349 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1350 "stream (malformed nvlist)"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1351 return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1352 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1353 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1354 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1355
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1356 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1357 recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1358 int baselen, char *newname, recvflags_t flags)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1359 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1360 static int seq;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1361 zfs_cmd_t zc = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1362 int err;
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1363 prop_changelist_t *clp;
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1364 zfs_handle_t *zhp;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1365
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1366 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1367 if (zhp == NULL)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1368 return (-1);
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1369 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1370 flags.force ? MS_FORCE : 0);
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1371 zfs_close(zhp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1372 if (clp == NULL)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1373 return (-1);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1374 err = changelist_prefix(clp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1375 if (err)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1376 return (err);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1377
10242
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1378 zc.zc_objset_type = DMU_OST_ZFS;
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1379 (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1380
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1381 if (tryname) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1382 (void) strcpy(newname, tryname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1383
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1384 (void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1385
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1386 if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1387 (void) printf("attempting rename %s to %s\n",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1388 zc.zc_name, zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1389 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1390 err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1391 if (err == 0)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1392 changelist_rename(clp, name, tryname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1393 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1394 err = ENOENT;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1395 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1396
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1397 if (err != 0 && strncmp(name+baselen, "recv-", 5) != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1398 seq++;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1399
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1400 (void) strncpy(newname, name, baselen);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1401 (void) snprintf(newname+baselen, ZFS_MAXNAMELEN-baselen,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1402 "recv-%u-%u", getpid(), seq);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1403 (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1404
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1405 if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1406 (void) printf("failed - trying rename %s to %s\n",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1407 zc.zc_name, zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1408 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1409 err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1410 if (err == 0)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1411 changelist_rename(clp, name, newname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1412 if (err && flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1413 (void) printf("failed (%u) - "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1414 "will try again on next pass\n", errno);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1415 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1416 err = EAGAIN;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1417 } else if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1418 if (err == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1419 (void) printf("success\n");
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1420 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1421 (void) printf("failed (%u)\n", errno);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1422 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1423
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1424 (void) changelist_postfix(clp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1425 changelist_free(clp);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1426
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1427 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1428 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1429
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1430 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1431 recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1432 char *newname, recvflags_t flags)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1433 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1434 zfs_cmd_t zc = { 0 };
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1435 int err = 0;
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1436 prop_changelist_t *clp;
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1437 zfs_handle_t *zhp;
10242
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1438 boolean_t defer = B_FALSE;
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1439 int spa_version;
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1440
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1441 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1442 if (zhp == NULL)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1443 return (-1);
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1444 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1445 flags.force ? MS_FORCE : 0);
10242
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1446 if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1447 zfs_spa_version(zhp, &spa_version) == 0 &&
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1448 spa_version >= SPA_VERSION_USERREFS)
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1449 defer = B_TRUE;
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1450 zfs_close(zhp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1451 if (clp == NULL)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1452 return (-1);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1453 err = changelist_prefix(clp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1454 if (err)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1455 return (err);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1456
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1457 zc.zc_objset_type = DMU_OST_ZFS;
10242
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1458 zc.zc_defer_destroy = defer;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1459 (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1460
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1461 if (flags.verbose)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1462 (void) printf("attempting destroy %s\n", zc.zc_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1463 err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1464 if (err == 0) {
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1465 if (flags.verbose)
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1466 (void) printf("success\n");
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1467 changelist_remove(clp, zc.zc_name);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1468 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1469
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1470 (void) changelist_postfix(clp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1471 changelist_free(clp);
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1472
10242
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1473 /*
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1474 * Deferred destroy should always succeed. Since we can't tell
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1475 * if it destroyed the dataset or just marked it for deferred
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1476 * destroy, always do the rename just in case.
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1477 */
c40d075fbca6 PSARC/2009/297 zfs snapshot holds
Chris Kirby <chris.kirby@sun.com>
parents: 10200
diff changeset
1478 if (err != 0 || defer)
6047
235fee4665e7 6598604 BAD TRAP while set property to multiple filesystems
ahrens
parents: 5896
diff changeset
1479 err = recv_rename(hdl, name, NULL, baselen, newname, flags);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1480
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1481 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1482 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1483
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1484 typedef struct guid_to_name_data {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1485 uint64_t guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1486 char *name;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1487 } guid_to_name_data_t;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1488
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1489 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1490 guid_to_name_cb(zfs_handle_t *zhp, void *arg)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1491 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1492 guid_to_name_data_t *gtnd = arg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1493 int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1494
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1495 if (zhp->zfs_dmustats.dds_guid == gtnd->guid) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1496 (void) strcpy(gtnd->name, zhp->zfs_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1497 return (EEXIST);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1498 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1499 err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1500 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1501 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1502 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1503
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1504 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1505 guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1506 char *name)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1507 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1508 /* exhaustive search all local snapshots */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1509 guid_to_name_data_t gtnd;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1510 int err = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1511 zfs_handle_t *zhp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1512 char *cp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1513
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1514 gtnd.guid = guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1515 gtnd.name = name;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1516
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1517 if (strchr(parent, '@') == NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1518 zhp = make_dataset_handle(hdl, parent);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1519 if (zhp != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1520 err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1521 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1522 if (err == EEXIST)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1523 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1524 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1525 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1526
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1527 cp = strchr(parent, '/');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1528 if (cp)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1529 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1530 zhp = make_dataset_handle(hdl, parent);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1531 if (cp)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1532 *cp = '/';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1533
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1534 if (zhp) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1535 err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1536 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1537 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1538
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1539 return (err == EEXIST ? 0 : ENOENT);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1540
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1541 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1542
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1543 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1544 * Return true if dataset guid1 is created before guid2.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1545 */
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1546 static int
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1547 created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1548 uint64_t guid1, uint64_t guid2)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1549 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1550 nvlist_t *nvfs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1551 char *fsname, *snapname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1552 char buf[ZFS_MAXNAMELEN];
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1553 int rv;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1554 zfs_node_t zn1, zn2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1555
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1556 if (guid2 == 0)
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1557 return (0);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1558 if (guid1 == 0)
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1559 return (1);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1560
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1561 nvfs = fsavl_find(avl, guid1, &snapname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1562 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1563 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1564 zn1.zn_handle = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1565 if (zn1.zn_handle == NULL)
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1566 return (-1);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1567
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1568 nvfs = fsavl_find(avl, guid2, &snapname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1569 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1570 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1571 zn2.zn_handle = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1572 if (zn2.zn_handle == NULL) {
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1573 zfs_close(zn2.zn_handle);
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1574 return (-1);
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1575 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1576
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1577 rv = (zfs_snapshot_compare(&zn1, &zn2) == -1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1578
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1579 zfs_close(zn1.zn_handle);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1580 zfs_close(zn2.zn_handle);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1581
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1582 return (rv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1583 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1584
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1585 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1586 recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1587 recvflags_t flags, nvlist_t *stream_nv, avl_tree_t *stream_avl)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1588 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1589 nvlist_t *local_nv;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1590 avl_tree_t *local_avl;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1591 nvpair_t *fselem, *nextfselem;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1592 char *tosnap, *fromsnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1593 char newname[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1594 int error;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1595 boolean_t needagain, progress;
10299
80845694147f 6696858 zfs receive of incremental replication stream can dereference NULL pointer and crash
Prabahar Jeyaram <Prabahar.Jeyaram@Sun.COM>
parents: 10242
diff changeset
1596 char *s1, *s2;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1597
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1598 VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1599 VERIFY(0 == nvlist_lookup_string(stream_nv, "tosnap", &tosnap));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1600
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1601 if (flags.dryrun)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1602 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1603
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1604 again:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1605 needagain = progress = B_FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1606
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1607 if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1608 &local_nv, &local_avl)) != 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1609 return (error);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1610
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1611 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1612 * Process deletes and renames
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1613 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1614 for (fselem = nvlist_next_nvpair(local_nv, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1615 fselem; fselem = nextfselem) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1616 nvlist_t *nvfs, *snaps;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1617 nvlist_t *stream_nvfs = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1618 nvpair_t *snapelem, *nextsnapelem;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1619 uint64_t fromguid = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1620 uint64_t originguid = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1621 uint64_t stream_originguid = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1622 uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1623 char *fsname, *stream_fsname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1624
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1625 nextfselem = nvlist_next_nvpair(local_nv, fselem);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1626
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1627 VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1628 VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1629 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1630 VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1631 &parent_fromsnap_guid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1632 (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1633
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1634 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1635 * First find the stream's fs, so we can check for
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1636 * a different origin (due to "zfs promote")
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1637 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1638 for (snapelem = nvlist_next_nvpair(snaps, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1639 snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1640 uint64_t thisguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1641
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1642 VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1643 stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1644
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1645 if (stream_nvfs != NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1646 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1647 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1648
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1649 /* check for promote */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1650 (void) nvlist_lookup_uint64(stream_nvfs, "origin",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1651 &stream_originguid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1652 if (stream_nvfs && originguid != stream_originguid) {
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1653 switch (created_before(hdl, local_avl,
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1654 stream_originguid, originguid)) {
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1655 case 1: {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1656 /* promote it! */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1657 zfs_cmd_t zc = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1658 nvlist_t *origin_nvfs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1659 char *origin_fsname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1660
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1661 if (flags.verbose)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1662 (void) printf("promoting %s\n", fsname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1663
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1664 origin_nvfs = fsavl_find(local_avl, originguid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1665 NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1666 VERIFY(0 == nvlist_lookup_string(origin_nvfs,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1667 "name", &origin_fsname));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1668 (void) strlcpy(zc.zc_value, origin_fsname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1669 sizeof (zc.zc_value));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1670 (void) strlcpy(zc.zc_name, fsname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1671 sizeof (zc.zc_name));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1672 error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1673 if (error == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1674 progress = B_TRUE;
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1675 break;
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1676 }
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1677 default:
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1678 break;
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1679 case -1:
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1680 fsavl_destroy(local_avl);
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1681 nvlist_free(local_nv);
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
1682 return (-1);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1683 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1684 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1685 * We had/have the wrong origin, therefore our
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1686 * list of snapshots is wrong. Need to handle
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1687 * them on the next pass.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1688 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1689 needagain = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1690 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1691 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1692
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1693 for (snapelem = nvlist_next_nvpair(snaps, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1694 snapelem; snapelem = nextsnapelem) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1695 uint64_t thisguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1696 char *stream_snapname;
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1697 nvlist_t *found, *props;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1698
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1699 nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1700
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1701 VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1702 found = fsavl_find(stream_avl, thisguid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1703 &stream_snapname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1704
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1705 /* check for delete */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1706 if (found == NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1707 char name[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1708
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1709 if (!flags.force)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1710 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1711
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1712 (void) snprintf(name, sizeof (name), "%s@%s",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1713 fsname, nvpair_name(snapelem));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1714
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1715 error = recv_destroy(hdl, name,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1716 strlen(fsname)+1, newname, flags);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1717 if (error)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1718 needagain = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1719 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1720 progress = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1721 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1722 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1723
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1724 stream_nvfs = found;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1725
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1726 if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1727 &props) && 0 == nvlist_lookup_nvlist(props,
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1728 stream_snapname, &props)) {
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1729 zfs_cmd_t zc = { 0 };
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1730
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1731 zc.zc_cookie = B_TRUE; /* clear current props */
7273
6baaca4d907c 6701797 want user properties on snapshots (fix lint)
ahrens
parents: 7265
diff changeset
1732 (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1733 "%s@%s", fsname, nvpair_name(snapelem));
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1734 if (zcmd_write_src_nvlist(hdl, &zc,
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1735 props) == 0) {
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1736 (void) zfs_ioctl(hdl,
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1737 ZFS_IOC_SET_PROP, &zc);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1738 zcmd_free_nvlists(&zc);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1739 }
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1740 }
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
1741
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1742 /* check for different snapname */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1743 if (strcmp(nvpair_name(snapelem),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1744 stream_snapname) != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1745 char name[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1746 char tryname[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1747
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1748 (void) snprintf(name, sizeof (name), "%s@%s",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1749 fsname, nvpair_name(snapelem));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1750 (void) snprintf(tryname, sizeof (name), "%s@%s",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1751 fsname, stream_snapname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1752
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1753 error = recv_rename(hdl, name, tryname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1754 strlen(fsname)+1, newname, flags);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1755 if (error)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1756 needagain = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1757 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1758 progress = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1759 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1760
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1761 if (strcmp(stream_snapname, fromsnap) == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1762 fromguid = thisguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1763 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1764
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1765 /* check for delete */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1766 if (stream_nvfs == NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1767 if (!flags.force)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1768 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1769
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1770 error = recv_destroy(hdl, fsname, strlen(tofs)+1,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1771 newname, flags);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1772 if (error)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1773 needagain = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1774 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1775 progress = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1776 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1777 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1778
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1779 if (fromguid == 0 && flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1780 (void) printf("local fs %s does not have fromsnap "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1781 "(%s in stream); must have been deleted locally; "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1782 "ignoring\n", fsname, fromsnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1783 continue;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1784 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1785
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1786 VERIFY(0 == nvlist_lookup_string(stream_nvfs,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1787 "name", &stream_fsname));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1788 VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1789 "parentfromsnap", &stream_parent_fromsnap_guid));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1790
10302
a9e3d1987706 6696858 zfs receive of incremental replication stream can dereference NULL pointer and crash (fix lint)
Prabahar Jeyaram <Prabahar.Jeyaram@Sun.COM>
parents: 10299
diff changeset
1791 s1 = strrchr(fsname, '/');
a9e3d1987706 6696858 zfs receive of incremental replication stream can dereference NULL pointer and crash (fix lint)
Prabahar Jeyaram <Prabahar.Jeyaram@Sun.COM>
parents: 10299
diff changeset
1792 s2 = strrchr(stream_fsname, '/');
a9e3d1987706 6696858 zfs receive of incremental replication stream can dereference NULL pointer and crash (fix lint)
Prabahar Jeyaram <Prabahar.Jeyaram@Sun.COM>
parents: 10299
diff changeset
1793
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1794 /* check for rename */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1795 if ((stream_parent_fromsnap_guid != 0 &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1796 stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
10302
a9e3d1987706 6696858 zfs receive of incremental replication stream can dereference NULL pointer and crash (fix lint)
Prabahar Jeyaram <Prabahar.Jeyaram@Sun.COM>
parents: 10299
diff changeset
1797 ((s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1798 nvlist_t *parent;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1799 char tryname[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1800
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1801 parent = fsavl_find(local_avl,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1802 stream_parent_fromsnap_guid, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1803 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1804 * NB: parent might not be found if we used the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1805 * tosnap for stream_parent_fromsnap_guid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1806 * because the parent is a newly-created fs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1807 * we'll be able to rename it after we recv the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1808 * new fs.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1809 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1810 if (parent != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1811 char *pname;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1812
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1813 VERIFY(0 == nvlist_lookup_string(parent, "name",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1814 &pname));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1815 (void) snprintf(tryname, sizeof (tryname),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1816 "%s%s", pname, strrchr(stream_fsname, '/'));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1817 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1818 tryname[0] = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1819 if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1820 (void) printf("local fs %s new parent "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1821 "not found\n", fsname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1822 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1823 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1824
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1825 error = recv_rename(hdl, fsname, tryname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1826 strlen(tofs)+1, newname, flags);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1827 if (error)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1828 needagain = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1829 else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1830 progress = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1831 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1832 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1833
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1834 fsavl_destroy(local_avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1835 nvlist_free(local_nv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1836
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1837 if (needagain && progress) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1838 /* do another pass to fix up temporary names */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1839 if (flags.verbose)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1840 (void) printf("another pass:\n");
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1841 goto again;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1842 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1843
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1844 return (needagain);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1845 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1846
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1847 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1848 zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1849 recvflags_t flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1850 char **top_zfs)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1851 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1852 nvlist_t *stream_nv = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1853 avl_tree_t *stream_avl = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1854 char *fromsnap = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1855 char tofs[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1856 char errbuf[1024];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1857 dmu_replay_record_t drre;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1858 int error;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1859 boolean_t anyerr = B_FALSE;
6479
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6476
diff changeset
1860 boolean_t softerr = B_FALSE;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1861
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1862 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1863 "cannot receive"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1864
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1865 if (strchr(destname, '@')) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1866 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1867 "can not specify snapshot name for multi-snapshot stream"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1868 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1869 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1870
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1871 assert(drr->drr_type == DRR_BEGIN);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1872 assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1873 assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1874 DMU_COMPOUNDSTREAM);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1875
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1876 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1877 * Read in the nvlist from the stream.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1878 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1879 if (drr->drr_payloadlen != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1880 if (!flags.isprefix) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1881 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1882 "must use -d to receive replication "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1883 "(send -R) stream"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1884 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1885 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1886
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1887 error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1888 &stream_nv, flags.byteswap, zc);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1889 if (error) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1890 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1891 goto out;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1892 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1893 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1894
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1895 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1896 * Read in the end record and verify checksum.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1897 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1898 if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1899 flags.byteswap, NULL)))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1900 goto out;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1901 if (flags.byteswap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1902 drre.drr_type = BSWAP_32(drre.drr_type);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1903 drre.drr_u.drr_end.drr_checksum.zc_word[0] =
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1904 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1905 drre.drr_u.drr_end.drr_checksum.zc_word[1] =
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1906 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1907 drre.drr_u.drr_end.drr_checksum.zc_word[2] =
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1908 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1909 drre.drr_u.drr_end.drr_checksum.zc_word[3] =
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1910 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1911 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1912 if (drre.drr_type != DRR_END) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1913 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1914 goto out;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1915 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1916 if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1917 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1918 "incorrect header checksum"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1919 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1920 goto out;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1921 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1922
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1923 (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1924
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1925 if (drr->drr_payloadlen != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1926 nvlist_t *stream_fss;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1927
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1928 VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1929 &stream_fss));
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
1930 if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
1931 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
1932 "couldn't allocate avl tree"));
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
1933 error = zfs_error(hdl, EZFS_NOMEM, errbuf);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
1934 goto out;
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
1935 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1936
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1937 if (fromsnap != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1938 (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1939 if (flags.isprefix) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1940 int i = strcspn(drr->drr_u.drr_begin.drr_toname,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1941 "/@");
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1942 /* zfs_receive_one() will create_parents() */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1943 (void) strlcat(tofs,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1944 &drr->drr_u.drr_begin.drr_toname[i],
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1945 ZFS_MAXNAMELEN);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1946 *strchr(tofs, '@') = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1947 }
6479
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6476
diff changeset
1948 softerr = recv_incremental_replication(hdl, tofs,
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1949 flags, stream_nv, stream_avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1950 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1951 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1952
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1953
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1954 /* Finally, receive each contained stream */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1955 do {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1956 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1957 * we should figure out if it has a recoverable
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1958 * error, in which case do a recv_skip() and drive on.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1959 * Note, if we fail due to already having this guid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1960 * zfs_receive_one() will take care of it (ie,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1961 * recv_skip() and return 0).
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1962 */
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1963 error = zfs_receive_impl(hdl, destname, flags, fd,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
1964 stream_avl, top_zfs);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1965 if (error == ENODATA) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1966 error = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1967 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1968 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1969 anyerr |= error;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1970 } while (error == 0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1971
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1972 if (drr->drr_payloadlen != 0 && fromsnap != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1973 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1974 * Now that we have the fs's they sent us, try the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1975 * renames again.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1976 */
6479
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6476
diff changeset
1977 softerr = recv_incremental_replication(hdl, tofs, flags,
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1978 stream_nv, stream_avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1979 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1980
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1981 out:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1982 fsavl_destroy(stream_avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1983 if (stream_nv)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1984 nvlist_free(stream_nv);
6479
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6476
diff changeset
1985 if (softerr)
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6476
diff changeset
1986 error = -2;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1987 if (anyerr)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1988 error = -1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1989 return (error);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1990 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1991
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1992 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1993 recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1994 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1995 dmu_replay_record_t *drr;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
1996 void *buf = malloc(1<<20);
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1997 char errbuf[1024];
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1998
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
1999 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2000 "cannot receive:"));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2001
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2002 /* XXX would be great to use lseek if possible... */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2003 drr = buf;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2004
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2005 while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2006 byteswap, NULL) == 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2007 if (byteswap)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2008 drr->drr_type = BSWAP_32(drr->drr_type);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2009
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2010 switch (drr->drr_type) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2011 case DRR_BEGIN:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2012 /* NB: not to be used on v2 stream packages */
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2013 if (drr->drr_payloadlen != 0) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2014 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2015 "invalid substream header"));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2016 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2017 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2018 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2019
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2020 case DRR_END:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2021 free(buf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2022 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2023
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2024 case DRR_OBJECT:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2025 if (byteswap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2026 drr->drr_u.drr_object.drr_bonuslen =
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2027 BSWAP_32(drr->drr_u.drr_object.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2028 drr_bonuslen);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2029 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2030 (void) recv_read(hdl, fd, buf,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2031 P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2032 B_FALSE, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2033 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2034
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2035 case DRR_WRITE:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2036 if (byteswap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2037 drr->drr_u.drr_write.drr_length =
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2038 BSWAP_64(drr->drr_u.drr_write.drr_length);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2039 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2040 (void) recv_read(hdl, fd, buf,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2041 drr->drr_u.drr_write.drr_length, B_FALSE, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2042 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2043
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2044 case DRR_WRITE_BYREF:
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2045 case DRR_FREEOBJECTS:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2046 case DRR_FREE:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2047 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2048
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2049 default:
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2050 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2051 "invalid record type"));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2052 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2053 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2054 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2055
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2056 free(buf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2057 return (-1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2058 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2059
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2060 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2061 * Restores a backup of tosnap from the file descriptor specified by infd.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2062 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2063 static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2064 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2065 recvflags_t flags, dmu_replay_record_t *drr,
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2066 dmu_replay_record_t *drr_noswap, avl_tree_t *stream_avl,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2067 char **top_zfs)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2068 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2069 zfs_cmd_t zc = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2070 time_t begin_time;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2071 int ioctl_err, ioctl_errno, err, choplen;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2072 char *cp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2073 struct drr_begin *drrb = &drr->drr_u.drr_begin;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2074 char errbuf[1024];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2075 char chopprefix[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2076 boolean_t newfs = B_FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2077 boolean_t stream_wantsnewfs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2078 uint64_t parent_snapguid = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2079 prop_changelist_t *clp = NULL;
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2080 nvlist_t *snapprops_nvlist = NULL;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2081
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2082 begin_time = time(NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2083
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2084 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2085 "cannot receive"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2086
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2087 if (stream_avl != NULL) {
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2088 char *snapname;
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2089 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2090 &snapname);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2091 nvlist_t *props;
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2092 int ret;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2093
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2094 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2095 &parent_snapguid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2096 err = nvlist_lookup_nvlist(fs, "props", &props);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2097 if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2098 VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2099
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2100 if (flags.canmountoff) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2101 VERIFY(0 == nvlist_add_uint64(props,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2102 zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2103 }
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2104 ret = zcmd_write_src_nvlist(hdl, &zc, props);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2105 if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2106 nvlist_free(props);
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2107
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2108 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2109 VERIFY(0 == nvlist_lookup_nvlist(props,
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2110 snapname, &snapprops_nvlist));
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2111 }
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2112
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2113 if (ret != 0)
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2114 return (-1);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2115 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2116
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2117 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2118 * Determine how much of the snapshot name stored in the stream
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2119 * we are going to tack on to the name they specified on the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2120 * command line, and how much we are going to chop off.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2121 *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2122 * If they specified a snapshot, chop the entire name stored in
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2123 * the stream.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2124 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2125 (void) strcpy(chopprefix, drrb->drr_toname);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2126 if (flags.isprefix) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2127 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2128 * They specified a fs with -d, we want to tack on
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2129 * everything but the pool name stored in the stream
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2130 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2131 if (strchr(tosnap, '@')) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2132 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2133 "argument - snapshot not allowed with -d"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2134 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2135 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2136 cp = strchr(chopprefix, '/');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2137 if (cp == NULL)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2138 cp = strchr(chopprefix, '@');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2139 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2140 } else if (strchr(tosnap, '@') == NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2141 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2142 * If they specified a filesystem without -d, we want to
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2143 * tack on everything after the fs specified in the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2144 * first name from the stream.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2145 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2146 cp = strchr(chopprefix, '@');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2147 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2148 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2149 choplen = strlen(chopprefix);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2150
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2151 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2152 * Determine name of destination snapshot, store in zc_value.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2153 */
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2154 (void) strcpy(zc.zc_top_ds, tosnap);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2155 (void) strcpy(zc.zc_value, tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2156 (void) strncat(zc.zc_value, drrb->drr_toname+choplen,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2157 sizeof (zc.zc_value));
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2158 if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2159 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2160 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2161 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2162
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2163 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2164 * Determine the name of the origin snapshot, store in zc_string.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2165 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2166 if (drrb->drr_flags & DRR_FLAG_CLONE) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2167 if (guid_to_name(hdl, tosnap,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2168 drrb->drr_fromguid, zc.zc_string) != 0) {
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2169 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2170 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2171 "local origin for clone %s does not exist"),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2172 zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2173 return (zfs_error(hdl, EZFS_NOENT, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2174 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2175 if (flags.verbose)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2176 (void) printf("found clone origin %s\n", zc.zc_string);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2177 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2178
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2179 stream_wantsnewfs = (drrb->drr_fromguid == NULL ||
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2180 (drrb->drr_flags & DRR_FLAG_CLONE));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2181
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2182 if (stream_wantsnewfs) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2183 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2184 * if the parent fs does not exist, look for it based on
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2185 * the parent snap GUID
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2186 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2187 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2188 "cannot receive new filesystem stream"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2189
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2190 (void) strcpy(zc.zc_name, zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2191 cp = strrchr(zc.zc_name, '/');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2192 if (cp)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2193 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2194 if (cp &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2195 !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2196 char suffix[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2197 (void) strcpy(suffix, strrchr(zc.zc_value, '/'));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2198 if (guid_to_name(hdl, tosnap, parent_snapguid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2199 zc.zc_value) == 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2200 *strchr(zc.zc_value, '@') = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2201 (void) strcat(zc.zc_value, suffix);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2202 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2203 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2204 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2205 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2206 * if the fs does not exist, look for it based on the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2207 * fromsnap GUID
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2208 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2209 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2210 "cannot receive incremental stream"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2211
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2212 (void) strcpy(zc.zc_name, zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2213 *strchr(zc.zc_name, '@') = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2214
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2215 if (!zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2216 char snap[ZFS_MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2217 (void) strcpy(snap, strchr(zc.zc_value, '@'));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2218 if (guid_to_name(hdl, tosnap, drrb->drr_fromguid,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2219 zc.zc_value) == 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2220 *strchr(zc.zc_value, '@') = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2221 (void) strcat(zc.zc_value, snap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2222 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2223 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2224 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2225
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2226 (void) strcpy(zc.zc_name, zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2227 *strchr(zc.zc_name, '@') = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2228
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2229 if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2230 zfs_handle_t *zhp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2231 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2232 * Destination fs exists. Therefore this should either
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2233 * be an incremental, or the stream specifies a new fs
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2234 * (full stream or clone) and they want us to blow it
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2235 * away (and have therefore specified -F and removed any
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2236 * snapshots).
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2237 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2238
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2239 if (stream_wantsnewfs) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2240 if (!flags.force) {
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2241 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2242 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2243 "destination '%s' exists\n"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2244 "must specify -F to overwrite it"),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2245 zc.zc_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2246 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2247 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2248 if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2249 &zc) == 0) {
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2250 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2251 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2252 "destination has snapshots (eg. %s)\n"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2253 "must destroy them to overwrite it"),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2254 zc.zc_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2255 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2256 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2257 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2258
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2259 if ((zhp = zfs_open(hdl, zc.zc_name,
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2260 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2261 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2262 return (-1);
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2263 }
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2264
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2265 if (stream_wantsnewfs &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2266 zhp->zfs_dmustats.dds_origin[0]) {
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2267 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2268 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2269 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2270 "destination '%s' is a clone\n"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2271 "must destroy it to overwrite it"),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2272 zc.zc_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2273 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2274 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2275
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2276 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2277 stream_wantsnewfs) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2278 /* We can't do online recv in this case */
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2279 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2280 if (clp == NULL) {
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
2281 zfs_close(zhp);
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2282 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2283 return (-1);
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2284 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2285 if (changelist_prefix(clp) != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2286 changelist_free(clp);
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
2287 zfs_close(zhp);
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2288 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2289 return (-1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2290 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2291 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2292 zfs_close(zhp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2293 } else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2294 /*
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2295 * Destination filesystem does not exist. Therefore we better
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2296 * be creating a new filesystem (either from a full backup, or
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2297 * a clone). It would therefore be invalid if the user
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2298 * specified only the pool name (i.e. if the destination name
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2299 * contained no slash character).
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2300 */
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2301 if (!stream_wantsnewfs ||
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2302 (cp = strrchr(zc.zc_name, '/')) == NULL) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2303 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2304 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2305 "destination '%s' does not exist"), zc.zc_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2306 return (zfs_error(hdl, EZFS_NOENT, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2307 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2308
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2309 /*
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2310 * Trim off the final dataset component so we perform the
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2311 * recvbackup ioctl to the filesystems's parent.
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2312 */
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2313 *cp = '\0';
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2314
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2315 if (flags.isprefix && !flags.dryrun &&
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2316 create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2317 zcmd_free_nvlists(&zc);
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2318 return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2319 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2320
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2321 newfs = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2322 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2323
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2324 zc.zc_begin_record = drr_noswap->drr_u.drr_begin;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2325 zc.zc_cookie = infd;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2326 zc.zc_guid = flags.force;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2327 if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2328 (void) printf("%s %s stream of %s into %s\n",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2329 flags.dryrun ? "would receive" : "receiving",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2330 drrb->drr_fromguid ? "incremental" : "full",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2331 drrb->drr_toname, zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2332 (void) fflush(stdout);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2333 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2334
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2335 if (flags.dryrun) {
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2336 zcmd_free_nvlists(&zc);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2337 return (recv_skip(hdl, infd, flags.byteswap));
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2338 }
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2339
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2340 err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2341 ioctl_errno = errno;
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2342 zcmd_free_nvlists(&zc);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2343
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2344 if (err == 0 && snapprops_nvlist) {
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2345 zfs_cmd_t zc2 = { 0 };
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2346
7273
6baaca4d907c 6701797 want user properties on snapshots (fix lint)
ahrens
parents: 7265
diff changeset
2347 (void) strcpy(zc2.zc_name, zc.zc_value);
7265
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2348 if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2349 (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2350 zcmd_free_nvlists(&zc2);
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2351 }
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2352 }
cc18862247da PSARC/2008/483 ZFS clone -o
ahrens
parents: 6479
diff changeset
2353
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2354 if (err && (ioctl_errno == ENOENT || ioctl_errno == ENODEV)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2355 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2356 * It may be that this snapshot already exists,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2357 * in which case we want to consume & ignore it
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2358 * rather than failing.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2359 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2360 avl_tree_t *local_avl;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2361 nvlist_t *local_nv, *fs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2362 char *cp = strchr(zc.zc_value, '@');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2363
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2364 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2365 * XXX Do this faster by just iterating over snaps in
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2366 * this fs. Also if zc_value does not exist, we will
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2367 * get a strange "does not exist" error message.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2368 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2369 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2370 if (gather_nvlist(hdl, zc.zc_value, NULL, NULL,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2371 &local_nv, &local_avl) == 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2372 *cp = '@';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2373 fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2374 fsavl_destroy(local_avl);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2375 nvlist_free(local_nv);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2376
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2377 if (fs != NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2378 if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2379 (void) printf("snap %s already exists; "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2380 "ignoring\n", zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2381 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2382 ioctl_err = recv_skip(hdl, infd,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2383 flags.byteswap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2384 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2385 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2386 *cp = '@';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2387 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2388
5896
1e0712e8dd8b 6627877 zfs receive coredump with invalid destination name
ahl
parents: 5765
diff changeset
2389
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2390 if (ioctl_err != 0) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2391 switch (ioctl_errno) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2392 case ENODEV:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2393 cp = strchr(zc.zc_value, '@');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2394 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2395 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2396 "most recent snapshot of %s does not\n"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2397 "match incremental source"), zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2398 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2399 *cp = '@';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2400 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2401 case ETXTBSY:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2402 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2403 "destination %s has been modified\n"
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2404 "since most recent snapshot"), zc.zc_name);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2405 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2406 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2407 case EEXIST:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2408 cp = strchr(zc.zc_value, '@');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2409 if (newfs) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2410 /* it's the containing fs that exists */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2411 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2412 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2413 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2414 "destination already exists"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2415 (void) zfs_error_fmt(hdl, EZFS_EXISTS,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2416 dgettext(TEXT_DOMAIN, "cannot restore to %s"),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2417 zc.zc_value);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2418 *cp = '@';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2419 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2420 case EINVAL:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2421 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2422 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2423 case ECKSUM:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2424 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2425 "invalid stream (checksum mismatch)"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2426 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2427 break;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2428 default:
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2429 (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2430 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2431 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2432
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2433 /*
10588
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10342
diff changeset
2434 * Mount the target filesystem (if created). Also mount any
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10342
diff changeset
2435 * children of the target filesystem if we did a replication
dc03f981ea18 6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Eric Taylor <Eric.Taylor@Sun.COM>
parents: 10342
diff changeset
2436 * receive (indicated by stream_avl being non-NULL).
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2437 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2438 cp = strchr(zc.zc_value, '@');
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2439 if (cp && (ioctl_err == 0 || !newfs)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2440 zfs_handle_t *h;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2441
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2442 *cp = '\0';
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2443 h = zfs_open(hdl, zc.zc_value,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2444 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
2445 if (h != NULL) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2446 if (h->zfs_type == ZFS_TYPE_VOLUME) {
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2447 *cp = '@';
10200
636e9ab433b8 6858551 zfs receive did not mount all filesystems
Lori Alt <Lori.Alt@Sun.COM>
parents: 10195
diff changeset
2448 } else if (newfs || stream_avl) {
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2449 /*
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2450 * Track the first/top of hierarchy fs,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2451 * for mounting and sharing later.
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2452 */
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2453 if (top_zfs && *top_zfs == NULL)
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2454 *top_zfs = zfs_strdup(hdl, zc.zc_value);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2455 }
6476
dc9c8d972859 6691138 dump_filesystem() can lead to SIGSEGV
ahl
parents: 6047
diff changeset
2456 zfs_close(h);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2457 }
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2458 *cp = '@';
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2459 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2460
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2461 if (clp) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2462 err |= changelist_postfix(clp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2463 changelist_free(clp);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2464 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2465
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2466 if (err || ioctl_err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2467 return (-1);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2468
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2469 if (flags.verbose) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2470 char buf1[64];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2471 char buf2[64];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2472 uint64_t bytes = zc.zc_cookie;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2473 time_t delta = time(NULL) - begin_time;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2474 if (delta == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2475 delta = 1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2476 zfs_nicenum(bytes, buf1, sizeof (buf1));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2477 zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2478
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2479 (void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2480 buf1, delta, buf2);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2481 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2482
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2483 return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2484 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2485
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2486 static int
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2487 zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2488 int infd, avl_tree_t *stream_avl, char **top_zfs)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2489 {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2490 int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2491 dmu_replay_record_t drr, drr_noswap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2492 struct drr_begin *drrb = &drr.drr_u.drr_begin;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2493 char errbuf[1024];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2494 zio_cksum_t zcksum = { 0 };
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2495 uint64_t featureflags;
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2496 int hdrtype;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2497
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2498 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2499 "cannot receive"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2500
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2501 if (flags.isprefix &&
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2502 !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2503 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2504 "(%s) does not exist"), tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2505 return (zfs_error(hdl, EZFS_NOENT, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2506 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2507
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2508 /* read in the BEGIN record */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2509 if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2510 &zcksum)))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2511 return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2512
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2513 if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2514 /* It's the double end record at the end of a package */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2515 return (ENODATA);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2516 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2517
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2518 /* the kernel needs the non-byteswapped begin record */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2519 drr_noswap = drr;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2520
5446
51fbc14b301d 6421210 zfs rollback without unmounting
ahrens
parents: 5367
diff changeset
2521 flags.byteswap = B_FALSE;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2522 if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2523 /*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2524 * We computed the checksum in the wrong byteorder in
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2525 * recv_read() above; do it again correctly.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2526 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2527 bzero(&zcksum, sizeof (zio_cksum_t));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2528 fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2529 flags.byteswap = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2530
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2531 drr.drr_type = BSWAP_32(drr.drr_type);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2532 drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2533 drrb->drr_magic = BSWAP_64(drrb->drr_magic);
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2534 drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2535 drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2536 drrb->drr_type = BSWAP_32(drrb->drr_type);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2537 drrb->drr_flags = BSWAP_32(drrb->drr_flags);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2538 drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2539 drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2540 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2541
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2542 if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2543 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2544 "stream (bad magic number)"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2545 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2546 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2547
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2548 featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2549 hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2550
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2551 if (!DMU_STREAM_SUPPORTED(featureflags) ||
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2552 (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2553 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2554 "stream has unsupported feature, feature flags = %lx"),
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2555 featureflags);
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2556 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2557 }
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2558
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2559 if (strchr(drrb->drr_toname, '@') == NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2560 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2561 "stream (bad snapshot name)"));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2562 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2563 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2564
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2565 if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2566 return (zfs_receive_one(hdl, infd, tosnap, flags,
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2567 &drr, &drr_noswap, stream_avl, top_zfs));
11007
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2568 } else { /* must be DMU_COMPOUNDSTREAM */
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2569 assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
216d8396182e PSARC/2009/557 ZFS send dedup
Lori Alt <Lori.Alt@Sun.COM>
parents: 10960
diff changeset
2570 DMU_COMPOUNDSTREAM);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2571 return (zfs_receive_package(hdl, infd, tosnap, flags,
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2572 &drr, &zcksum, top_zfs));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2573 }
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents:
diff changeset
2574 }
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2575
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2576 /*
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2577 * Restores a backup of tosnap from the file descriptor specified by infd.
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2578 * Return 0 on total success, -2 if some things couldn't be
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2579 * destroyed/renamed/promoted, -1 if some things couldn't be received.
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2580 * (-1 will override -2).
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2581 */
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2582 int
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2583 zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2584 int infd, avl_tree_t *stream_avl)
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2585 {
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2586 char *top_zfs = NULL;
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2587 int err;
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2588
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2589 err = zfs_receive_impl(hdl, tosnap, flags, infd, stream_avl, &top_zfs);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2590
8584
327a1b6dd944 6794452 zfs receive can't restore a root pool
Lori Alt <Lori.Alt@Sun.COM>
parents: 7366
diff changeset
2591 if (err == 0 && !flags.nomount && top_zfs) {
7366
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2592 zfs_handle_t *zhp;
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2593 prop_changelist_t *clp;
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2594
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2595 zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2596 if (zhp != NULL) {
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2597 clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2598 CL_GATHER_MOUNT_ALWAYS, 0);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2599 zfs_close(zhp);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2600 if (clp != NULL) {
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2601 /* mount and share received datasets */
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2602 err = changelist_postfix(clp);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2603 changelist_free(clp);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2604 }
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2605 }
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2606 if (zhp == NULL || clp == NULL || err)
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2607 err = -1;
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2608 }
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2609 if (top_zfs)
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2610 free(top_zfs);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2611
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2612 return (err);
33de5956afbb 6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents: 7273
diff changeset
2613 }