[PATCH] blkzone: Add --force option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 missing initialization and too many periods in man page of
--verbose option.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx>
---
 sys-utils/blkzone.8 |  5 ++++-
 sys-utils/blkzone.c | 17 ++++++++++++++---
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/sys-utils/blkzone.8 b/sys-utils/blkzone.8
index f50e3f5df..64ad23bb3 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 62430e634..5c170127b 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;
 };
 
@@ -295,13 +296,16 @@ static int blkzone_action(struct blkzone_control *ctl)
 	struct blk_zone_range za = { .sector = 0 };
 	unsigned long zonesize;
 	uint64_t zlen;
-	int fd;
+	int fd, mode;
 
 	zonesize = blkdev_chunk_sectors(ctl->devname);
 	if (!zonesize)
 		errx(EXIT_FAILURE, _("%s: unable to determine zone size"), ctl->devname);
 
-	fd = init_device(ctl, O_WRONLY | O_EXCL);
+	mode = O_WRONLY;
+	if (!ctl->force)
+		mode |= O_EXCL;
+	fd = init_device(ctl, mode);
 
 	if (ctl->offset & (zonesize - 1))
 		errx(EXIT_FAILURE, _("%s: offset %" PRIu64 " is not aligned "
@@ -362,6 +366,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));
@@ -382,12 +387,15 @@ int main(int argc, char **argv)
 		.count = 0,
 		.length = 0
 	};
+	ctl.force = 0;
+	ctl.verbose = 0;
 
 	static const struct option longopts[] = {
 	    { "help",    no_argument,       NULL, 'h' },
 	    { "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 +420,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 +437,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.25.4




[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux