aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libzfs_core
diff options
context:
space:
mode:
authorLOLi <[email protected]>2017-05-10 01:21:09 +0200
committerBrian Behlendorf <[email protected]>2017-05-09 16:21:09 -0700
commita3eeab2de68670a4481eab3d086982aff23b6906 (patch)
tree5e3da58bca04309596df84dd84b591e8631eae0f /lib/libzfs_core
parent305bc4b370b20de81eaf10a1cf724374258b74d1 (diff)
Add property overriding (-o|-x) to 'zfs receive'
This allows users to specify "-o property=value" to override and "-x property" to exclude properties when receiving a zfs send stream. Both native and user properties can be specified. This is useful when using zfs send/receive for periodic backup/replication because it lets users change properties such as canmount, mountpoint, or compression without modifying the source. References: https://www.illumos.org/issues/2745 https://www.illumos.org/issues/3753 Reviewed by: Matthew Ahrens <[email protected]> Reviewed-by: Alek Pinchuk <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: loli10K <[email protected]> Closes #1350 Closes #5349
Diffstat (limited to 'lib/libzfs_core')
-rw-r--r--lib/libzfs_core/libzfs_core.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c
index 591e769dd..17f9931a0 100644
--- a/lib/libzfs_core/libzfs_core.c
+++ b/lib/libzfs_core/libzfs_core.c
@@ -574,8 +574,8 @@ recv_read(int fd, void *buf, int ilen)
* Non-Linux OpenZFS platforms have opted to modify the legacy interface.
*/
static int
-recv_impl(const char *snapname, nvlist_t *props, const char *origin,
- boolean_t force, boolean_t resumable, int input_fd,
+recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
+ const char *origin, boolean_t force, boolean_t resumable, int input_fd,
const dmu_replay_record_t *begin_record, int cleanup_fd,
uint64_t *read_bytes, uint64_t *errflags, uint64_t *action_handle,
nvlist_t **errors)
@@ -622,8 +622,11 @@ recv_impl(const char *snapname, nvlist_t *props, const char *origin,
fnvlist_add_string(innvl, "snapname", snapname);
- if (props != NULL)
- fnvlist_add_nvlist(innvl, "props", props);
+ if (recvdprops != NULL)
+ fnvlist_add_nvlist(innvl, "props", recvdprops);
+
+ if (localprops != NULL)
+ fnvlist_add_nvlist(innvl, "localprops", localprops);
if (origin != NULL && strlen(origin))
fnvlist_add_string(innvl, "origin", origin);
@@ -679,12 +682,18 @@ recv_impl(const char *snapname, nvlist_t *props, const char *origin,
(void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_value));
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
- if (props != NULL) {
- packed = fnvlist_pack(props, &size);
+ if (recvdprops != NULL) {
+ packed = fnvlist_pack(recvdprops, &size);
zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
zc.zc_nvlist_src_size = size;
}
+ if (localprops != NULL) {
+ packed = fnvlist_pack(localprops, &size);
+ zc.zc_nvlist_conf = (uint64_t)(uintptr_t)packed;
+ zc.zc_nvlist_conf_size = size;
+ }
+
if (origin != NULL)
(void) strlcpy(zc.zc_string, origin,
sizeof (zc.zc_string));
@@ -750,7 +759,7 @@ int
lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
boolean_t force, int fd)
{
- return (recv_impl(snapname, props, origin, force, B_FALSE, fd,
+ return (recv_impl(snapname, props, NULL, origin, force, B_FALSE, fd,
NULL, -1, NULL, NULL, NULL, NULL));
}
@@ -764,7 +773,7 @@ int
lzc_receive_resumable(const char *snapname, nvlist_t *props, const char *origin,
boolean_t force, int fd)
{
- return (recv_impl(snapname, props, origin, force, B_TRUE, fd,
+ return (recv_impl(snapname, props, NULL, origin, force, B_TRUE, fd,
NULL, -1, NULL, NULL, NULL, NULL));
}
@@ -786,7 +795,7 @@ lzc_receive_with_header(const char *snapname, nvlist_t *props,
{
if (begin_record == NULL)
return (EINVAL);
- return (recv_impl(snapname, props, origin, force, resumable, fd,
+ return (recv_impl(snapname, props, NULL, origin, force, resumable, fd,
begin_record, -1, NULL, NULL, NULL, NULL));
}
@@ -816,7 +825,26 @@ int lzc_receive_one(const char *snapname, nvlist_t *props,
uint64_t *read_bytes, uint64_t *errflags, uint64_t *action_handle,
nvlist_t **errors)
{
- return (recv_impl(snapname, props, origin, force, resumable,
+ return (recv_impl(snapname, props, NULL, origin, force, resumable,
+ input_fd, begin_record, cleanup_fd, read_bytes, errflags,
+ action_handle, errors));
+}
+
+/*
+ * Like lzc_receive_one, but allows the caller to pass an additional 'cmdprops'
+ * argument.
+ *
+ * The 'cmdprops' nvlist contains both override ('zfs receive -o') and
+ * exclude ('zfs receive -x') properties. Callers are responsible for freeing
+ * this nvlist
+ */
+int lzc_receive_with_cmdprops(const char *snapname, nvlist_t *props,
+ nvlist_t *cmdprops, const char *origin, boolean_t force,
+ boolean_t resumable, int input_fd, const dmu_replay_record_t *begin_record,
+ int cleanup_fd, uint64_t *read_bytes, uint64_t *errflags,
+ uint64_t *action_handle, nvlist_t **errors)
+{
+ return (recv_impl(snapname, props, cmdprops, origin, force, resumable,
input_fd, begin_record, cleanup_fd, read_bytes, errflags,
action_handle, errors));
}