Skip to content

zpool create: warn on suboptimal pool layout#14754

Draft
robn wants to merge 1 commit intoopenzfs:masterfrom
robn:reject-suboptimal-layout
Draft

zpool create: warn on suboptimal pool layout#14754
robn wants to merge 1 commit intoopenzfs:masterfrom
robn:reject-suboptimal-layout

Conversation

@robn
Copy link
Member

@robn robn commented Apr 16, 2023

Motivation and Context

Its possible to create pools that are perfectly valid but are perhaps not the "best" choice for a given set of hardware.

An example is a raidz1 of two devices. I have seen inexperienced users create this because it looks on the surface like a traditional RAID-1, that is, a mirror. It even appears to work, but presents problems later when they want to upgrade the drives, and of course does not perform as well as a mirror.

It seems to me that if we can guide users towards the "right" way to use ZFS without too much effort, we should try, and this is an attempt at that.

Description

This changes zpool create to reject such "suboptimal" pool layouts, and suggest a possible better alternative. It adds a switch, --force-layout, to disable the check and the warning and return the old behaviour, for those who know what they're doing.

Only the above example is checked for, but with the structure in place it'll be easy to add more as we like.

How Has This Been Tested?

New tests added for the new feature.

Many existing tests attempt to create raidz1 vdevs with two devices, and those are now failing. Its not hard to identify and fix them by adding --force-layout, but that feels brittle. An alternative solution might be an environment variable to disable the checks (or maybe one of the test suite environment variables). Suggestions welcome.

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)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

Copy link
Contributor

@mcmilk mcmilk left a comment

Choose a reason for hiding this comment

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

I like the idea - and also the implementation looks good.

Edit: the new tests look also okay, but may need some more real testing.

@rincebrain
Copy link
Contributor

rincebrain commented Apr 16, 2023

Could I propose you change it from --force-layout to --force=layout, the better to extend it with more fine-grained force parameters later without requiring a sea of --force-a --force-b --force-c?

Maybe I'm alone in that preference, though. :(

edit: Might also be worth noting that raidz1 is not a mirror in the output, since a lot of people I've encountered who did this seemed to assume "raidz" meant 'ZFS magic raid of any kind".

@behlendorf
Copy link
Contributor

Could I propose you change it from --force-layout to --force=layout

This would be nice since it finally provides a consist way to override a warnings by type. For example, creating a pool with different levels of parity among the top-level vdev needs to be forced. We've long wanted to be able to override just this warning and not all warnings.

I'm not sure which I prefer, but --allow=layout would be another option.

@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Apr 18, 2023
@robn
Copy link
Member Author

robn commented Apr 26, 2023

Thanks for the feedback.

I'm kind of indifferent to --force=... just for this PR, but I can certainly see the utility of a general facility to be able to express this kind of thing. So I'll put this hold until I can get around to putting that together. This weekend I hope.

That helps with the test case too; I think I'll make it default to the ZPOOL_FORCE= environment variable (or something of that shape).

@robn robn marked this pull request as draft April 26, 2023 11:11
@robn robn force-pushed the reject-suboptimal-layout branch from 35184ba to f0a8059 Compare June 4, 2023 01:26
@allanjude
Copy link
Contributor

Being able to pick and choose what -f overrides has been on my wish list since 2016.

I am even kind of partial to the --allow= instead of force.
for zpool create and zpool add

  1. different number of members
  2. different raidz level
  3. mix of raidz and not
  4. different disk sizes
  5. disk was part of a previous pool
    etc

so something like: --allow=count,used to cover 1 and 5, but NOT 4

and for import even, --allow=hostid to suppress that one check, but not others.

@robn robn force-pushed the reject-suboptimal-layout branch from f0a8059 to 8e477cf Compare July 15, 2023 12:05
@robn
Copy link
Member Author

robn commented Jul 15, 2023

Alright, latest push sets up --force as a set of comma-separated flags, and adds two: vdevs, which is the old -f behaviour, and layout, which is the override flag for this PR.

root@quiz:/# zpool create tank raidz1 loop0 loop1
suboptimal vdev specification: a 'raidz1' vdev with 2 devices is inefficient; consider 'mirror' instead.
use '--force=layout' to ignore this.
root@quiz:/# zpool create --force=layout tank raidz1 loop0 loop1
root@quiz:/# zpool export -a
root@quiz:/# zpool create tank raidz1 loop0 loop1
invalid vdev specification
use '-f' to override the following errors:
/dev/loop0 is part of exported pool 'tank'
/dev/loop1 is part of exported pool 'tank'
root@quiz:/# zpool create -f tank raidz1 loop0 loop1
suboptimal vdev specification: a 'raidz1' vdev with 2 devices is inefficient; consider 'mirror' instead.
use '--force=layout' to ignore this.
root@quiz:/# zpool create --force=layout tank raidz1 loop0 loop1
invalid vdev specification
use '-f' to override the following errors:
/dev/loop0 is part of exported pool 'tank'
/dev/loop1 is part of exported pool 'tank'
root@quiz:/# zpool create --force=vdevs,layout tank raidz1 loop0 loop1
root@quiz:/# zpool status
  pool: tank
 state: ONLINE
config:

	NAME        STATE     READ WRITE CKSUM
	tank        ONLINE       0     0     0
	 raidz1-0  ONLINE       0     0     0
	   loop0   ONLINE       0     0     0
	   loop1   ONLINE       0     0     0

errors: No known data errors

There's a new utility function, zpool_option_flag_apply(), which is set up to play nicely with long options. I haven't used it anywhere else (we don't have anything else yet!) and it would be better as a common function for zfs as well, but we don't have any shared code like that really. That can come later.

Tests will still fail because they try to make "suboptimal" pools in places. Probably I will just add --force=layout in any places that will definitely cause problems, since it can now be specified precisely. Possibly better would be an environment variable eg ZPOOL_FORCE=layout that is automatically hooked up, but I wouldn't want to do that without some agreement that there will be a common set of forcible things across all subcommands, so it makes sense in the future.

The flag parsing and the suboptimal layout warning are of course unrelated, and I would ordinarily split something like this into two PRs, but just adding the utility function in its own PR without anything using it is kind of equally silly, so it stays here for now.

Anyway, all comments welcome!

Its possible to create pools that are perfectly valid but are perhaps
not the "best" choice for a given set of devices.

An example is a raidz1 of two devices. I have seen inexperienced users
create this because it looks on the surface like a traditional RAID-1,
that is, a mirror. It even appears to work, but presents problems later
when they want to upgrade the drives, and of course does not perform as
well as a mirror.

This changes `zpool create` to reject such "suboptimal" pool layouts,
and suggest a possible better alternative. It checks for raidz and draid
where the number of devices are parity+1, and could be extended in the
future.

It adds a switch, --force=layout, to disable the check and the warning
and return the old behaviour, for those who know what they're doing.

Included is a utility function to work with option flags. The existing
-f switch to `zpool create` is now an alias for `--force=vdevs`.

Signed-off-by: Rob Norris <robn@despairlabs.com>
@robn robn force-pushed the reject-suboptimal-layout branch from f5ead99 to 82580a8 Compare January 4, 2026 23:21
@robn
Copy link
Member Author

robn commented Jan 4, 2026

Rebased to master, no other changes.

Note that I still want this. I'm getting around to lifting the "flagopts" code but I want to do something specific that uses it too. I've got an audit of all the -f and -F force flags in progress (for a couple of years, I touch it every few months) to categorise them all. Unless something else shows up, it'll be that: adding --force=<category> flags to everything. Then this would go over the top of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Code Review Needed Ready for review and testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants