From 9cd88771ef45b50ff791306c48b41dbbabe31241 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 27 May 2020 16:58:08 +0200 Subject: [PATCH] fdisk: add --lock and LOCK_BLOCK_DEVICE Addresses: https://github.com/karelzak/util-linux/issues/921 Signed-off-by: Karel Zak --- disk-utils/fdisk.8 | 10 ++++++++++ disk-utils/fdisk.c | 29 +++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/disk-utils/fdisk.8 b/disk-utils/fdisk.8 index bb6e0588b6..e84782c461 100644 --- a/disk-utils/fdisk.8 +++ b/disk-utils/fdisk.8 @@ -86,6 +86,14 @@ If no devices are given, those mentioned in \fB\-x\fR, \fB\-\-list\-details\fR Like \fB\-\-list\fR, but provides more details. .TP +\fB\-\-lock\fR[=\fImode\fR] +Use exclusive BSD lock for device or file it operates. The optional argument +\fImode\fP can be \fByes\fR, \fBno\fR (or 1 and 0) or \fBnonblock\fR. If the \fImode\fR +argument is omitted, it defaults to \fB"yes"\fR. This option overwrites +environment variable \fB$LOCK_BLOCK_DEVICE\fR. The default is not to use any +lock at all, but it's recommended to avoid collisions with udevd or other +tools. +.TP \fB\-n\fR, \fB\-\-noauto\-pt\fR Don't automatically create a default partition table on empty device. The partition table has to be explicitly created by user (by command like 'o', 'g', etc.). @@ -357,6 +365,8 @@ enables libblkid debug output. enables libsmartcols debug output. .IP LIBSMARTCOLS_DEBUG_PADDING=on use visible padding characters. Requires enabled LIBSMARTCOLS_DEBUG. +.IP LOCK_BLOCK_DEVICE= +use exclusive BSD lock. The mode is "1" or "0". See \fB\-\-lock\fR for more details. .SH AUTHORS .MT kzak@redhat.com diff --git a/disk-utils/fdisk.c b/disk-utils/fdisk.c index bf5307b62f..f802d44c46 100644 --- a/disk-utils/fdisk.c +++ b/disk-utils/fdisk.c @@ -873,6 +873,8 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -u, --units[=] display units: 'cylinders' or 'sectors' (default)\n"), out); fputs(_(" -s, --getsz display device size in 512-byte sectors [DEPRECATED]\n"), out); fputs(_(" --bytes print SIZE in bytes rather than in human readable format\n"), out); + fprintf(out, + _(" --lock[=] use exclusive device lock (%s, %s or %s)\n"), "yes", "no", "nonblock"); fprintf(out, _(" -w, --wipe wipe signatures (%s, %s or %s)\n"), "auto", "always", "never"); fprintf(out, @@ -906,8 +908,10 @@ int main(int argc, char **argv) int colormode = UL_COLORMODE_UNDEF; struct fdisk_context *cxt; char *outarg = NULL; + const char *devname, *lockmode = NULL; enum { - OPT_BYTES = CHAR_MAX + 1 + OPT_BYTES = CHAR_MAX + 1, + OPT_LOCK }; static const struct option longopts[] = { { "bytes", no_argument, NULL, OPT_BYTES }, @@ -920,6 +924,7 @@ int main(int argc, char **argv) { "help", no_argument, NULL, 'h' }, { "list", no_argument, NULL, 'l' }, { "list-details", no_argument, NULL, 'x' }, + { "lock", optional_argument, NULL, OPT_LOCK }, { "noauto-pt", no_argument, NULL, 'n' }, { "sector-size", required_argument, NULL, 'b' }, { "type", required_argument, NULL, 't' }, @@ -1056,6 +1061,14 @@ int main(int argc, char **argv) case OPT_BYTES: fdisk_set_size_unit(cxt, FDISK_SIZEUNIT_BYTES); break; + case OPT_LOCK: + lockmode = "1"; + if (optarg) { + if (*optarg == '=') + optarg++; + lockmode = optarg; + } + break; default: errtryhelp(EXIT_FAILURE); } @@ -1119,17 +1132,25 @@ int main(int argc, char **argv) fdisk_info(cxt, _("Changes will remain in memory only, until you decide to write them.\n" "Be careful before using the write command.\n")); - rc = fdisk_assign_device(cxt, argv[optind], 0); + devname = argv[optind]; + rc = fdisk_assign_device(cxt, devname, 0); if (rc == -EACCES) { - rc = fdisk_assign_device(cxt, argv[optind], 1); + rc = fdisk_assign_device(cxt, devname, 1); if (rc == 0) fdisk_warnx(cxt, _("Device is open in read-only mode.")); } if (rc) - err(EXIT_FAILURE, _("cannot open %s"), argv[optind]); + err(EXIT_FAILURE, _("cannot open %s"), devname); fflush(stdout); + if (!fdisk_is_readonly(cxt) + && blkdev_lock(fdisk_get_devfd(cxt), devname, lockmode) != 0) { + fdisk_deassign_device(cxt, 1); + fdisk_unref_context(cxt); + return EXIT_FAILURE; + } + if (fdisk_get_collision(cxt)) follow_wipe_mode(cxt); -- 2.39.5