From b8671fe76370436beb37ca65ea1563c3284a2699 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 27 May 2020 16:58:08 +0200 Subject: [PATCH] mkswap: add --lock and LOCK_BLOCK_DEVICE Addresses: https://github.com/karelzak/util-linux/issues/921 Signed-off-by: Karel Zak --- disk-utils/mkswap.8 | 10 ++++++++++ disk-utils/mkswap.c | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/disk-utils/mkswap.8 b/disk-utils/mkswap.8 index 81ad133b4f..a8cbcc20ae 100644 --- a/disk-utils/mkswap.8 +++ b/disk-utils/mkswap.8 @@ -76,6 +76,14 @@ Specify a \fIlabel\fR for the device, to allow .B swapon by label. .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 .BR \-p , " \-\-pagesize " \fIsize\fR Specify the page \fIsize\fR (in bytes) to use. This option is usually unnecessary; .B mkswap @@ -102,6 +110,8 @@ Display version information and exit. .SH ENVIRONMENT .IP LIBBLKID_DEBUG=all enables libblkid debug output. +.IP LOCK_BLOCK_DEVICE= +use exclusive BSD lock. The mode is "1" or "0". See \fB\-\-lock\fR for more details. .SH NOTES The maximum useful size of a swap area depends on the architecture and diff --git a/disk-utils/mkswap.c b/disk-utils/mkswap.c index c6aaaf5f1b..4fb8415362 100644 --- a/disk-utils/mkswap.c +++ b/disk-utils/mkswap.c @@ -53,6 +53,7 @@ struct mkswap_control { void *signature_page;/* buffer with swap header */ char *devname; /* device or file name */ + const char *lockmode; /* as specified by --lock */ struct stat devstat; /* stat() result */ int fd; /* swap file descriptor */ @@ -161,6 +162,8 @@ static void __attribute__((__noreturn__)) usage(void) " -v, --swapversion NUM specify swap-space version number\n" " -U, --uuid UUID specify the uuid to use\n" )); + fprintf(out, + _(" --lock[=] use exclusive device lock (%s, %s or %s)\n"), "yes", "no", "nonblock"); printf(USAGE_HELP_OPTIONS(27)); printf(USAGE_MAN_TAIL("mkswap(8)")); @@ -244,6 +247,10 @@ static void open_device(struct mkswap_control *ctl) ctl->fd = open_blkdev_or_file(&ctl->devstat, ctl->devname, O_RDWR); if (ctl->fd < 0) err(EXIT_FAILURE, _("cannot open %s"), ctl->devname); + + if (blkdev_lock(ctl->fd, ctl->devname, ctl->lockmode) != 0) + exit(EXIT_FAILURE); + if (ctl->check && S_ISREG(ctl->devstat.st_mode)) { ctl->check = 0; warnx(_("warning: checking bad blocks from swap file is not supported: %s"), @@ -354,6 +361,9 @@ int main(int argc, char **argv) const char *opt_uuid = NULL; uuid_t uuid_dat; #endif + enum { + OPT_LOCK = CHAR_MAX + 1, + }; static const struct option longopts[] = { { "check", no_argument, NULL, 'c' }, { "force", no_argument, NULL, 'f' }, @@ -363,6 +373,7 @@ int main(int argc, char **argv) { "uuid", required_argument, NULL, 'U' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, + { "lock", optional_argument, NULL, OPT_LOCK }, { NULL, 0, NULL, 0 } }; @@ -401,6 +412,15 @@ int main(int argc, char **argv) break; case 'V': print_version(EXIT_SUCCESS); + break; + case OPT_LOCK: + ctl.lockmode = "1"; + if (optarg) { + if (*optarg == '=') + optarg++; + ctl.lockmode = optarg; + } + break; case 'h': usage(); default: -- 2.47.2