OpenZFS 6051 - lzc_receive: allow the caller to read the begin record
Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Paul Dagnelie <pcd@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Ported-by: Brian Behlendorf <behlendorf1@llnl.gov> OpenZFS-issue: https://www.illumos.org/issues/6051 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/620f322
This commit is contained in:
parent
47dfff3b86
commit
fd41e93563
@ -60,10 +60,15 @@ enum lzc_send_flags {
|
||||
int lzc_send(const char *, const char *, int, enum lzc_send_flags);
|
||||
int lzc_send_resume(const char *, const char *, int,
|
||||
enum lzc_send_flags, uint64_t, uint64_t);
|
||||
int lzc_send_space(const char *, const char *, uint64_t *);
|
||||
|
||||
struct dmu_replay_record;
|
||||
|
||||
int lzc_receive(const char *, nvlist_t *, const char *, boolean_t, int);
|
||||
int lzc_receive_resumable(const char *, nvlist_t *, const char *,
|
||||
boolean_t, int);
|
||||
int lzc_send_space(const char *, const char *, uint64_t *);
|
||||
int lzc_receive_with_header(const char *, nvlist_t *, const char *, boolean_t,
|
||||
boolean_t, int, const struct dmu_replay_record *);
|
||||
|
||||
boolean_t lzc_exists(const char *);
|
||||
|
||||
|
@ -548,8 +548,9 @@ recv_read(int fd, void *buf, int ilen)
|
||||
}
|
||||
|
||||
static int
|
||||
lzc_receive_impl(const char *snapname, nvlist_t *props, const char *origin,
|
||||
boolean_t force, boolean_t resumable, int fd)
|
||||
recv_impl(const char *snapname, nvlist_t *props, const char *origin,
|
||||
boolean_t force, boolean_t resumable, int fd,
|
||||
const dmu_replay_record_t *begin_record)
|
||||
{
|
||||
/*
|
||||
* The receive ioctl is still legacy, so we need to construct our own
|
||||
@ -594,9 +595,14 @@ lzc_receive_impl(const char *snapname, nvlist_t *props, const char *origin,
|
||||
(void) strlcpy(zc.zc_string, origin, sizeof (zc.zc_string));
|
||||
|
||||
/* zc_begin_record is non-byteswapped BEGIN record */
|
||||
error = recv_read(fd, &zc.zc_begin_record, sizeof (zc.zc_begin_record));
|
||||
if (error != 0)
|
||||
goto out;
|
||||
if (begin_record == NULL) {
|
||||
error = recv_read(fd, &zc.zc_begin_record,
|
||||
sizeof (zc.zc_begin_record));
|
||||
if (error != 0)
|
||||
goto out;
|
||||
} else {
|
||||
zc.zc_begin_record = *begin_record;
|
||||
}
|
||||
|
||||
/* zc_cookie is fd to read from */
|
||||
zc.zc_cookie = fd;
|
||||
@ -637,7 +643,7 @@ int
|
||||
lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
|
||||
boolean_t force, int fd)
|
||||
{
|
||||
return (lzc_receive_impl(snapname, props, origin, force, B_FALSE, fd));
|
||||
return (recv_impl(snapname, props, origin, force, B_FALSE, fd, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -650,7 +656,29 @@ int
|
||||
lzc_receive_resumable(const char *snapname, nvlist_t *props, const char *origin,
|
||||
boolean_t force, int fd)
|
||||
{
|
||||
return (lzc_receive_impl(snapname, props, origin, force, B_TRUE, fd));
|
||||
return (recv_impl(snapname, props, origin, force, B_TRUE, fd, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Like lzc_receive, but allows the caller to read the begin record and then to
|
||||
* pass it in. That could be useful if the caller wants to derive, for example,
|
||||
* the snapname or the origin parameters based on the information contained in
|
||||
* the begin record.
|
||||
* The begin record must be in its original form as read from the stream,
|
||||
* in other words, it should not be byteswapped.
|
||||
*
|
||||
* The 'resumable' parameter allows to obtain the same behavior as with
|
||||
* lzc_receive_resumable.
|
||||
*/
|
||||
int
|
||||
lzc_receive_with_header(const char *snapname, nvlist_t *props,
|
||||
const char *origin, boolean_t force, boolean_t resumable, int fd,
|
||||
const dmu_replay_record_t *begin_record)
|
||||
{
|
||||
if (begin_record == NULL)
|
||||
return (EINVAL);
|
||||
return (recv_impl(snapname, props, origin, force, resumable, fd,
|
||||
begin_record));
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user