From 6e103c7690fe4c07ea9dfe45c52c4c22e0281d0b Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Fri, 5 Jun 2020 14:06:18 +0900 Subject: [PATCH] blkzone: Add --force option Commit 7a2602f629fe ("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 Signed-off-by: Karel Zak --- sys-utils/blkzone.8 | 5 ++++- sys-utils/blkzone.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sys-utils/blkzone.8 b/sys-utils/blkzone.8 index f50e3f5df8..64ad23bb31 100644 --- a/sys-utils/blkzone.8 +++ b/sys-utils/blkzone.8 @@ -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. diff --git a/sys-utils/blkzone.c b/sys-utils/blkzone.c index 62430e6340..c983448319 100644 --- a/sys-utils/blkzone.c +++ b/sys-utils/blkzone.c @@ -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 start sector of zone to act (in 512-byte sectors)\n"), out); fputs(_(" -l, --length maximum sectors to act (in 512-byte sectors)\n"), out); fputs(_(" -c, --count 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; -- 2.47.2