blkzone: Add --force option

Commit 7a2602f629 ("blkzone: deny destructive ioctls on busy blockdev")
introduced exclusive mode to open block devices to submit zone management
ioctls. This avoids unintended status change of block devices used by the
system. However, it makes blkzone less usable for testing. For example,
the test case zbd/007 of blktests utilizes blkzone to reset zones of
block devices mapped to dm-linear devices. After the commit, the test
case fails with EBUSY error at blkzone reset, since the system uses the
reset target block device to map to the dm-linear device.

To allow blkzone to change status of zoned block devices used by the
system with intention, introduce --force option. With this option, block
devices are opened without exclusive mode.

Also fix too many periods in man page of --verbose option.

[kzak@redhat.com: - tiny cosmetic changes]

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Shin'ichiro Kawasaki 2020-06-05 14:06:18 +09:00 committed by Karel Zak
parent 9bf622dad9
commit 6e103c7690
2 changed files with 12 additions and 3 deletions

View File

@ -107,9 +107,12 @@ The maximum number of zones the command should operate on. The default value
is the number of zones starting from \fIoffset\fR. This option cannot be
used together with the option \fB\-\-length\fP.
.TP
.BR \-f , " \-\-force"
Enforce commands to change zone status on block devices used by the system.
.TP
.BR \-v , " \-\-verbose"
Display the number of zones returned in the report or the range of sectors
reset..
reset.
.TP
.BR \-V , " \-\-version"
Display version information and exit.

View File

@ -81,6 +81,7 @@ struct blkzone_control {
uint64_t length;
uint32_t count;
unsigned int force : 1;
unsigned int verbose : 1;
};
@ -301,7 +302,7 @@ static int blkzone_action(struct blkzone_control *ctl)
if (!zonesize)
errx(EXIT_FAILURE, _("%s: unable to determine zone size"), ctl->devname);
fd = init_device(ctl, O_WRONLY | O_EXCL);
fd = init_device(ctl, O_WRONLY | (ctl->force ? 0 : O_EXCL));
if (ctl->offset & (zonesize - 1))
errx(EXIT_FAILURE, _("%s: offset %" PRIu64 " is not aligned "
@ -362,6 +363,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -o, --offset <sector> start sector of zone to act (in 512-byte sectors)\n"), out);
fputs(_(" -l, --length <sectors> maximum sectors to act (in 512-byte sectors)\n"), out);
fputs(_(" -c, --count <number> maximum number of zones\n"), out);
fputs(_(" -f, --force enforce on block devices used by the system\n"), out);
fputs(_(" -v, --verbose display more details\n"), out);
fputs(USAGE_SEPARATOR, out);
printf(USAGE_HELP_OPTIONS(24));
@ -388,6 +390,7 @@ int main(int argc, char **argv)
{ "count", required_argument, NULL, 'c' }, /* max #of zones to operate on */
{ "length", required_argument, NULL, 'l' }, /* max of sectors to operate on */
{ "offset", required_argument, NULL, 'o' }, /* starting LBA */
{ "force", no_argument, NULL, 'f' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
@ -412,7 +415,7 @@ int main(int argc, char **argv)
argc--;
}
while ((c = getopt_long(argc, argv, "hc:l:o:vV", longopts, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "hc:l:o:fvV", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
@ -429,6 +432,9 @@ int main(int argc, char **argv)
ctl.offset = strtosize_or_err(optarg,
_("failed to parse zone offset"));
break;
case 'f':
ctl.force = 1;
break;
case 'v':
ctl.verbose = 1;
break;