]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
mkswap: add --lock and LOCK_BLOCK_DEVICE
authorKarel Zak <kzak@redhat.com>
Wed, 27 May 2020 14:58:08 +0000 (16:58 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 27 May 2020 14:59:16 +0000 (16:59 +0200)
Addresses: https://github.com/karelzak/util-linux/issues/921
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/mkswap.8
disk-utils/mkswap.c

index 81ad133b4f16498ff568613986221b80889a7da3..a8cbcc20ae140fc201f04c212c3284955cd5fb43 100644 (file)
@@ -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=<mode>
+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
index c6aaaf5f1b6348a6f0815f838746e3ca0453a0d2..4fb84153627845d2e62a05977774e6b96f92e7d8 100644 (file)
@@ -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[=<mode>]       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: