Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zfs promote .../%recv should be an error #6339

Merged
merged 1 commit into from
Jul 28, 2017

Conversation

loli10K
Copy link
Contributor

@loli10K loli10K commented Jul 12, 2017

Description

Add more input validation in zfs_ioc_promote() (and its userland counterpart) so we don't promote temporary ".../%recv" datasets.

NOTE: I have not added tests to cover my changes yet: should we update "zfs_promote_006_neg.ksh" ('zfs promote' will fail with invalid arguments) or add a new script?

Motivation and Context

Fix #4843

If we are in the middle of an incremental zfs receive, the child .../%recv will exist. If you concurrently run zfs promote .../%recv, it will "work", but then zfs gets confused. For example, there's no obvious way to destroy the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by having zfs_ioc_promote() check if zc_name contains a %, similar to zfs_ioc_rename().

How Has This Been Tested?

POOLNAME='testpool'
TMPDIR='/var/tmp'
mountpoint -q $TMPDIR || mount -t tmpfs tmpfs $TMPDIR
zpool destroy $POOLNAME
rm -f $TMPDIR/zpool.dat
fallocate -l 256m $TMPDIR/zpool.dat
zpool create -O mountpoint=$TMPDIR/$POOLNAME $POOLNAME $TMPDIR/zpool.dat
#
zfs create $POOLNAME/src -o mountpoint=$TMPDIR/$POOLNAME/src
#
dd if=/dev/urandom of=/$TMPDIR/$POOLNAME/src/file.dat bs=1M count=10
zfs snap $POOLNAME/src@snap1
#
dd if=/dev/urandom of=/$TMPDIR/$POOLNAME/src/file.dat bs=1M count=10
zfs snap $POOLNAME/src@snap2
#
dd if=/dev/urandom of=/$TMPDIR/$POOLNAME/src/file.dat bs=1M count=10
zfs snap $POOLNAME/src@snap3
#
zfs send -p $POOLNAME/src@snap1 | zfs recv -vu $POOLNAME/dst
zfs send -pI $POOLNAME/src@snap1 $POOLNAME/src@snap3 | dd bs=1M count=15 iflag=fullblock | zfs recv -svu $POOLNAME/dst
#
zfs get name,inconsistent,mountpoint,origin $POOLNAME/dst/%recv
#
zfs promote $POOLNAME/dst/%recv

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to man pages or other documentation)

Checklist:

  • My code follows the ZFS on Linux code style requirements.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • All commit messages are properly formatted and contain Signed-off-by.
  • Change has been approved by a ZFS on Linux member.

Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to extended the existing zfs_promote_006_neg.ksh test case. It wouldn't be a terrible idea to extend the other *_neg test cases where a '%' in the name isn't allowed to check for this.

@@ -3751,6 +3751,10 @@ zfs_promote(zfs_handle_t *zhp)
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
}

if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE)) {
return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need for the { } here.

@loli10K
Copy link
Contributor Author

loli10K commented Jul 14, 2017

@behlendorf i'll update zfs_promote_006_neg.ksh and the other nit ASAP: I'm still trying to fix kstat collisions.

Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@loli10K no problem, and don't worry I know this isn't quite right to merge. I've reverted the approved status for now.

@@ -50,30 +51,44 @@
verify_runnable "both"

snap=$TESTPOOL/$TESTFS@$TESTSNAP
incr=$TESTPOOL/$TESTFS@incr$TESTSNAP
clone=$TESTPOOL/$TESTCLONE
destfs=$TESTPOOL/destfs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe recvfs instead of destfs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recvfs is objectively more appropriate here

Copy link
Contributor

@dinatale2 dinatale2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the corrections! Noticed one more thing. Do you mind squashing your commits as well?

typeset mountpoint="$TESTDIR/create_recv_clone"
typeset sendfile="$TESTDIR/create_recv_clone.zsnap"

[[ -z $recvfs ]] && log_fail "Recv filesystem's name is undefined."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could enforce recvfs doesn't exist by calling datasetexists and failing if that returns true. Likewise with sendfs, you'd want to make sure it doesn't exist.

@behlendorf
Copy link
Contributor

@loli10K when you get a chance could you rebase this on master.

If we are in the middle of an incremental 'zfs receive', the child
.../%recv will exist. If we run 'zfs promote' .../%recv, it will "work",
but then zfs gets confused about the status of the new dataset.
Attempting to do this promote should be an error.

Similarly renaming .../%recv datasets should not be allowed.

Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for rebasing this and extending the test coverage. This LGTM!

@behlendorf behlendorf merged commit 650258d into openzfs:master Jul 28, 2017
@loli10K loli10K deleted the issue-4843 branch August 3, 2017 17:59
uqs pushed a commit to freebsd/freebsd-src that referenced this pull request Feb 22, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>


git-svn-id: svn+ssh://svn.freebsd.org/base/head@329783 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
uqs pushed a commit to freebsd/freebsd-src that referenced this pull request Feb 22, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>
uqs pushed a commit to freebsd/freebsd-src that referenced this pull request Feb 22, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>
mat813 pushed a commit to mat813/freebsd that referenced this pull request Feb 22, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>


git-svn-id: https://svn.freebsd.org/base/vendor-sys/illumos/dist@329781 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
mat813 pushed a commit to mat813/freebsd that referenced this pull request Feb 22, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>


git-svn-id: https://svn.freebsd.org/base/head@329783 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
mat813 pushed a commit to mat813/freebsd that referenced this pull request Feb 22, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>


git-svn-id: https://svn.freebsd.org/base/vendor/illumos/dist@329781 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
bdrewery pushed a commit to bdrewery/freebsd that referenced this pull request Feb 26, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>


git-svn-id: svn+ssh://svn.freebsd.org/base/head@329783 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
uqs pushed a commit to freebsd/freebsd-src that referenced this pull request Apr 16, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>
mat813 pushed a commit to mat813/freebsd that referenced this pull request Apr 16, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>


git-svn-id: https://svn.freebsd.org/base/stable/11@332535 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
brooksdavis pushed a commit to CTSRD-CHERI/cheribsd that referenced this pull request Aug 17, 2018
illumos/illumos-gate@add927f

Reported on the ZFSonLinux openzfs/zfs#4843,
fixed by openzfs/zfs#6339:

If we are in the middle of an incremental zfs receive, the child .../%recv
will exist. If you concurrently run zfs promote .../%recv, it will "work",
but then zfs gets confused. For example, there's no obvious way to destroy
the containing filesystem (because it is now a clone of its invisible child).

Attempting to do this promote should be an error. We could fix this by
having zfs_ioc_promote() check if zc_name contains a %, similar to
zfs_ioc_rename().

Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: loli10K <ezomori.nozomu@gmail.com>
@loli10K loli10K restored the issue-4843 branch November 1, 2018 15:40
FransUrbo pushed a commit to FransUrbo/zfs that referenced this pull request Apr 28, 2019
If we are in the middle of an incremental 'zfs receive', the child
.../%recv will exist. If we run 'zfs promote' .../%recv, it will "work",
but then zfs gets confused about the status of the new dataset.
Attempting to do this promote should be an error.

Similarly renaming .../%recv datasets should not be allowed.

Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes openzfs#4843 
Closes openzfs#6339
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

zfs promote .../%recv should be an error
3 participants